现在的位置: 首页 > 综合 > 正文

正则表达式笔记两则

2013年05月18日 ⁄ 综合 ⁄ 共 1302字 ⁄ 字号 评论关闭

一:PHP对中文字符串的正则表达式匹配函数。
最近在学习正则表达式。于是用PHP写了一个简单的正则表达式测试工具。但是对于中文文本,匹配会问题。如:
文本:看看PHP是否匹配中文。
正则表达式:PHP.
匹配的输出结果:看看PHP�欠衿ヅ渲形摹�

在网上搜索,说是可以用[/u4e00-/u9fa5]匹配中文,但是PHP中明确说明:
Warning: preg_replace() [function.preg-replace]: Compilation failed: PCRE does not support /L, /l, /N, /U, or /u at offset 2 in D:/WebApplications/www/reg_test.php on line 34

最终的解决方法是用mb_系列的函数解决的。在使用mb_ereg_系列的适用于多字节字符集的正则表达式函数之前,需要先使用mb_regex_encoding函数设置一下多字节字符集的编码。默认的编码是IOS-8859-1。
对于上述文本正则表达式匹配,使用:
mb_regex_encoding(“GB2312”);
mb_ereg_XXX
即可。
使用PHP.匹配上述文本的结果是:
看看PHP是否匹配中文。
二:
在《正则表达式必知必会》第30页有这样一个例子,文本:
11213
A1C2E3
48075
48237
M1B4F2
90046
H1H2H2
正则表达式是:/w/d/w/d/w/d
匹配结果:

11213
A1C2E3
48075
48237
M1B4F2
90046
H1H2H2
红色部分是和正则表达式匹配的部分。总共有3处。/w是可以匹配数字、字母、下划线的。/d匹配数字。上面这种情况只能有一种解释,那就是正则表达式要求的是六个字符。所有那三个没有被匹配到的数字字符串才不会被匹配到。为了验证,写一个长为6的数字字符串再试试。在上面的文本末尾加上123456,这个时候的匹配结果是:
11213
A1C2E3
48075
48237
M1B4F2
90046
H1H2H2
123456
果然如此。那么,书上的“注意”那段话又怎么解释:

注意:在上面这个例子里,我们使用正则表达式解决了我们的问题。但它正确吗?请大家思考一下,为什么美国的邮政编码没有被匹配出来?是因为它们只由数字构成,还是因为什么其他原因?
       我们将不给出这个问题的答案,理由很简单——例子里的模式解决了问题。这里的关键是正则表达式很少有对错之分(当然,前提是它们能解决问题),我们更关心的是它们的复杂程序——而这要由模式匹配操作的精确程序来决定;如果你需要更精确的匹配,就需要构造更复杂的正则表达式。

可以作此理解,正则表达式的语法很容易学,但是如何使用正则表达式来解决实际问题,你写出来的正则表达式是不是你本来想要表达的意思,这才是一门大学问。在上面的例子中,如果目标文本不是美国邮政编码就是加拿大的邮政编码,那么上面的正则表达式是对的,它能正确匹配加拿大的邮政编码。甚至可以写成更简单的形式:/w{6}。但是,如果目标文本可能是任何情况,这种情况下就必须写出精确匹配加拿大邮政编码的正则表达式。
一个问题没有绝对的答案,最适合的才是最好的。

 

抱歉!评论已关闭.