如何用正则表达式匹配中文

前几天因为在做学校教务处的爬虫,用php抓取的成绩和课程表竟然返回的是html格式的数据,也是很醉。没办法,干脆用正则匹配吧。因为之前并没有学过正则表达式,只好恶补了一下。在匹配的过程中遇到了一些问题,特别是在匹配中文的时候,很是蛋疼。下面说一下我的学习成果。

  1. 使用php在匹配中文的时候不能使用 \w 来匹配,可以使用元字符 . 来粗略匹配中文
  2. 精确匹配中文时需要考虑编码环境,gb2312和 utf-8。这两种编码有什么区别呢 ? 最主要的就是gb2312编码的汉字占两个字节,而utf-8编码的汉字占3个字节。

一、好了,下面进入正题,如果你想匹配中文的话,可以采用下面的表达式:

utf-8编码:

[\x{4e00}-\x{9fa5}]
例如:匹配5个汉字,便可以这么写:

/[\x{4e00}-\x{9fa5}]{5}/u
千万注意,这个最后面的u一定要加上(如果是使用php的话),否则是无法正常匹配的。
二、通过上面的表达式我们可以匹配一段模糊的中文,那如果我们想要匹配精准的某个字或者词语呢 ?例如,我在做教务处爬虫时,抓取到的成绩不仅仅只是数字,还有优秀、通过、良好等。这种我们总不能漏掉吧? 可以使用下面的方式来匹配:

1. 先将汉字转换成为16进制Unicode编码,可以在这个网站方便的转换:Unicode与中文互转 16进制Unicode编码转换、还原

例如我们将 优秀 两个字转换成了该编码,为 :  \u4f18\u79c0

2. 匹配 优秀 两个汉字的正则表达式如下:

/\x{4f18}\x{79c0}/u

想必大家应该已经明白了,拿到16进制编码后,有这么几步,将u改为x, 再将具体的16进制编码加上{ },最后不要忘记加上u

三、包含换行段落的匹配

先给出一段需匹配的代码:

<span style="white-space:pre">	</span><tr class="H">
                <td class="td0" style='width:5%;padding:0px;' colspan='2'></td>
                <td class='td0' style="width:13%;height:20px;">
                    星期一
                </td>
                <td class='td0' style="width:13%;height:20px;">
                    星期二
                </td>
                <td class='td0' style="width:13%;height:20px;">
                    星期三
                </td>
                <td class='td0' style="width:13%;height:20px;">
                    星期四
                </td>
                <td class='td0' style="width:13%;height:20px;">
                    星期五
                </td>
                <td class='td0' style="width:13%;height:20px;">
                    星期六
                </td>
                <td class='td0' style="width:13%;height:20px;">
                    星期日
                </td>
<span style="white-space:pre">	</span></tr>
我们的目标是从这段html代码中抓取星期一   —  星期日,有人可能会说,直接匹配td标签,来个for循环就好了吗,但现在我只是给出一个例子,很多时候我们拿到的数据并不像这样有规律,所以成段匹配还是很有必要的。

我一开始尝试的方法是从<tr>匹配到</tr>, 将其中的汉字全部抓出来 ,但很不幸,失败了。原因就是在于其中的换行,那我们怎样才能匹配包含换行的文本呢 ?其实方法很简单,只要使用这个表达式:/[.\s\S]*/

我曾经试过使用 /[.\n]/  来匹配,但是并不可以。上面的表达式完美的解决了问题。

<think>首先,用户的问题是:“我想查找使用正则表达式匹配其他正则表达式匹配结果的方法 请问正则表达式匹配其他正则表达式匹配结果的方法”,翻译成英文是:“I want to find a method to use regex to match the results of other regex matches. How do I match regex results with regex?” 用户提到了几个引用,我需要参考它们。引用[1]是关于匹配浮点数的正则表达式,引用[2]是关于匹配IP地址和一些其他模式的正则表达式,引用[3]是关于匹配${xxx}这样的模板字符串的正则表达式。 用户的核心问题是:如何用正则表达式匹配其他正则表达式匹配结果。这意味着,用户可能有一个文本,其中包含一些已经由另一个正则表达式匹配的部分,用户想用一个新的正则表达式匹配那些特定的匹配结果。 在正则表达式中,匹配其他正则表达式匹配结果通常不是一个直接的功能,因为正则表达式是用于匹配文本模式的,而不是匹配其他匹配结果。但是,用户可能在问如何捕获和处理子匹配,或者在嵌套匹配上下文中使用正则表达式。 回顾引用[3],它讨论了匹配${xxx},并改进正则表达式来处理空格和操作符。这表明用户可能对捕获组和精确匹配感兴趣。 可能的解释: 1. **嵌套匹配**:用户可能想在一个文本中匹配某个模式,然后对那些匹配到的部分应用另一个正则表达式。这不是用单个正则表达式完成的,而是需要编程实现的:先用第一个正则表达式匹配所有位置,然后对每个匹配结果应用第二个正则表达式。 2. **引用捕获组**:在正则表达式中,捕获组可以存储部分匹配,用户可能想匹配这些捕获组的值。但正则表达式本身不能动态引用先前匹配的结果(除非在替换部分使用反向引用)。 用户说“匹配其他正则表达式匹配结果”,所以更可能指的是处理第一个正则表达式的输出。 在回答中,我需要: - 使用系统级指令:所有行内数学表达式用$...$,独立公式用$$...$$。 - 使用中文回答。 - 生成相关问题。 - 引用末尾添加引用标识。 结构化回答: 1. **解释问题**:澄清正则表达式匹配结果的本质。 2. **方法**:描述如何在编程中实现匹配匹配结果。 - 步骤1:使用第一个正则表达式扫描文本,获取所有匹配对象或字符串。 - 步骤2:对每个匹配的对象或字符串应用第二个正则表达式。 3. **举例**:基于引用来举例,比如引用[3]中的${xxx}匹配。 - 例如:首先用引用[3]的正则匹配所有${...},然后对每个匹配应用另一个正则表达式提取内容。 4. **正则表达式本身**:如果用户想在单个正则表达式中实现,可以使用捕获组和贪婪/非贪婪匹配,但会有限制。 在引用[3]中,它使用了\$\{(.*?)\}来匹配${和}之间的内容,然后可以进一步处理匹配的内容。 回答核心内容: - 正则表达式匹配结果是文本片段,因此可以用另一个正则表达式匹配它们。 - 在代码中,通常是先收集所有匹配,然后迭代处理。 生成相关问题: 1. 如何在Python中使用正则表达式处理嵌套匹配? 2. 正则表达式中捕获组的应用方法? 3. 如何处理复杂的文本模板匹配? 确保回答真实可靠。 最终回答大纲: - 介绍:正则表达式匹配结果是字符串,因此可以用其他正则表达式匹配。 - 详细方法:描述编程实现。 - 代码示例:使用Python的re模块,因为引用中有Python。 - 引用相关部分:比如引用[3]。 - 相关问题。 </think>### 正则表达式匹配其他正则表达式匹配结果的方法 在使用正则表达式时,匹配其他正则表达式匹配结果通常不是直接通过单个正则表达式完成的,因为正则表达式本身是静态模式匹配工具,无法直接动态引用其他匹配的文本片段。相反,这需要结合编程逻辑实现:**先用第一个正则表达式提取所有匹配结果(即文本片段),然后对这些片段应用第二个正则表达式进行进一步匹配**。这种方法常用于处理嵌套模式或复杂文本解析,例如从模板字符串中提取数据(如引用[3]中的${xxx}示例)。以下是详细解释和实现方法。 #### 核心概念 - **匹配结果本质**:正则表达式匹配结果是文本字符串(例如,从 "${bizDate+1}" 中提取的 "bizDate+1")。这些字符串可作为新正则表达式的输入。 - **编程实现流程**: 1. **步骤1: 应用第一个正则表达式**——扫描原始文本,获取所有匹配对象或匹配字符串的列表。 2. **步骤2: 应用第二个正则表达式**——对每个匹配结果(文本片段)应用第二个正则表达式,提取或验证子内容。 - **为什么不能单次完成**:正则表达式匹配是贪婪或非贪婪的模式搜索(如引用[3]使用非贪婪模式 `.*?`),但无法在单个表达式中直接“匹配匹配结果”。这需要迭代处理(常见于编程语言如Python、Java)。 #### 实现方法:以Python为例 以下代码演示如何先匹配引用[3]中的${xxx}模式,然后对每个匹配结果应用第二个正则表达式(例如提取变量名和操作符)。假设原始文本是SQL语句:`update demo1 set ptime=${bizDate+1} and date=${ bizDate }`。 ```python import re # 原始文本 text = "update demo1 set ptime=${bizDate+1} and date=${ bizDate }" # 步骤1: 应用第一个正则表达式匹配所有${xxx}片段(基于引用[3]的改进版) first_regex = r'\$\{\s*(\w+)\s*(([\+\-])\s*(\d+)\s*)?\}' # 匹配 ${xxx} 格式,并捕获内部内容 [^3] matches = re.finditer(first_regex, text) # 获取匹配迭代器 # 步骤2: 对每个匹配结果应用第二个正则表达式 second_regex = r'^(\w+)\s*([\+\-])?\s*(\d+)?$' # 针对内部内容的模式,提取变量名、操作符、数字 results = [] for match in matches: inner_content = match.group(0) # 完整匹配文本,如 "${bizDate+1}" clean_content = inner_content.strip('${}').strip() # 去除 ${} 符号,如 "bizDate+1" # 应用第二个正则表达式到清理后的内容 sub_match = re.match(second_regex, clean_content) if sub_match: variable = sub_match.group(1) # 提取变量名,如 "bizDate" operator = sub_match.group(2) if sub_match.group(2) else None # 提取操作符,如 "+" number = sub_match.group(3) if sub_match.group(3) else None # 提取数字,如 "1" results.append({ "full_match": inner_content, "variable": variable, "operator": operator, "number": number }) # 输出结果 print(results) # 示例输出: [{'full_match': '${bizDate+1}', 'variable': 'bizDate', 'operator': '+', 'number': '1'}, ...] ``` #### 关键点说明 1. **第一个正则表达式的作用**: - 使用 `\$\{\s*(\w+)\s*(([\+\-])\s*(\d+)\s*)?\}` 匹配 ${xxx} 格式(引用[3]的改进版)。这个表达式: - 匹配 `${` 和 `}`。 - 内部捕获变量名(`(\w+)`)和可选的操作符+数字(`(([\+\-])\s*(\d+)\s*)?`)。 - 非贪婪匹配确保处理空格(如 `${ bizDate }`)[^3]。 - 在代码中,`re.finditer` 返回所有匹配对象,便于后续处理。 2. **第二个正则表达式的作用**: - 针对清理后的内容(如 "bizDate+1"),使用 `^(\w+)\s*([\+\-])?\s*(\d+)?$` 进一步提取: - `^(\w+)`:匹配变量名开头。 - `\s*([\+\-])?`:可选的操作符(+或-)。 - `\s*(\d+)?$`:可选的数字结尾。 - 这允许对匹配的子内容进行精细化解析(例如区分变量和操作)。 3. **适用场景**: - 文本模板处理(如SQL、配置文件中提取动态变量)。 - 日志解析(先匹配时间戳,再匹配其中的日期部分)。 - 数据清洗(如先匹配浮点数,再提取其整数部分——引用[1]的正则可用于第一步)[^1]。 #### 注意事项 - **性能优化**:对于大文本,避免在循环中频繁编译正则表达式(可预编译:`re.compile`)。 - **工具支持**:在支持正则的编辑器或语言(如Python、JavaScript)中,此方法高效;正则表达式本身无法递归匹配。 - **局限性**:复杂嵌套(如正则匹配正则表达式)可能需要解析器而非纯正则,但上述方法是实用折中方案。 通过这种两步法,您可以高效匹配和处理其他正则表达式匹配结果[^1][^3]。
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值