正则表达式

来源:互联网 发布:古墓丽影崛起优化补丁 编辑:程序博客网 时间:2024/06/05 16:13
最近在学习正则表达式,发现原来理解的正则表达式不是特别的准确,甚至有误!在这里简单记录一下,希望对有的朋友能够有所帮助!


①“[]”:字符集(字符簇,字符组……)

他的真正含义是"或"的意思!例如:[123],它代表的含义是,匹配一个1或2或3!

由于它经常是用于匹配多个可能的值,所以支持一种简写的方式! 例如:[12345678]可以简写为[1-8]
[abcdefghjik]可以简写为[a-k] [1234567ABCDEFG]可以简写为[1-7A-G]

“[]”相关的陷阱!

(1)在”[]”中的大部分元字符都是普通字符,都不在具有元字符的含义!但是仍然有个别的元字符除外!
“-”,“^”,目前只知道这两个,可能还有其他的,待补充!

“-”,是作为连字符表示的是一个范围,
1. 如果单独的将“-”符号放在第一位的话,它表示的也是一个普通的字符!例如:[a-z]这个时候就是元字符,代表的是一个范围!
2. 在[-abc]中,"-"就是一个普通的字符,这句话就表示,匹配-、a、b、c中,这四个字符中的任意一个!

^有两个意思,
1. 在字符簇外,它表示的是托字节,匹配的是一个位置!
2. 而在字符簇中相当于取反的意思!而且只有当托字节放在字符簇的第一个位置的时候才会表示一个元字符!
  1. <p>    <?php</p><p>    $str =<<<STR</p><p>        Iraq</p><p>        Iraqian</p><p>        miqra</p><p>        qintar</p><p>        aoph</p><p>        zaqqnum</p><p>STR;</p><p>    $reg = '/q[^udfg]/';</p><p>    preg_match_all($reg, $str, $result);</p><p>    var_dump($result);</p>
复制代码
运行结果如下
  1. <p>array(1) { [0]=>array(5) { [0]=> string(2) "q " [1]=> string(2) "qi"[2]=> string(2) "qr" [3]=> string(2) "qi" [4]=>string(2) "qq" } }</p><p>?></p>
复制代码
曾经好长一段时间,我个人一直认为,[^udfg]匹配的是除了udfg中的任何一个字符,但是,很明显我错了! 通过上面我们对“[]”的了解,字符簇永远匹配的是一个字符!所以,他的正解应该是,匹配除了字符u外的任意一个字符,或者dfg中的任何一个字符!

可能会有的朋友问Iraq中q后面匹配了什么!答案是回车(在window状态下是\r\n)!\r并不属于u所以匹配成功!

有的工具会在匹陪前,将这些换行符号给换掉!所以有时候会匹配不到,但是,经过试验证明,在php中换行符是不会被去掉的!


②“|”表示或的意思!它代表一个分支语句!

到这里,可能有的朋友会问,那他的功能岂不是和 ”[]” 的功能重复了么?

答案显然是否定的!个人认为“|”,分支语句,在一定程度上弥补了“[]”符号功能的不足!因为“[]”,自始至终只能表示一个字字符!

例如:[a-z],他表示的匹配a-z中的任意一个字符!

而当我们需要匹配abc或def的时候,显然”[]”是无能为力的!而此时也正是“|”分支结构的用处!可以写成(abc|def)

表示匹配abc或者def这两个字符集中的一个!


③“?”表示可选项!它只作用于之前紧邻的元素!

这里我们需要明白一下元素的概念!所谓元素还包括如下的形式:[a-z]这个字符簇整体表示一个元素!(abc|def)这个分支结构整体表示一个元素!
注意:所有的量词都是仅作用于之前紧邻的元素!


④正则中的反向引用

在正则表达式中,使用”()”包裹起来的元素被统一称为子表达式!而括号是能够记忆“()”匹配到的内容的,无论这些匹配到的文本是什么!(这个也就是我们常说的反向引用!如果他是第一个的话使用\1,就可以获得字表达式中的内容!)

那么如果判断是表达式几呢?有一个原则:按照开括号“(”从左到右的出现顺序进行计算!依次就是\1,\2,\3…… 注意:反向引用应该是可以嵌套的!遵循的同样是这个原则!看代码:
  1. <p><?php</p><p>    $content = 'maweibin is the author';</p><p>    $regexp = "/(((ma)wei)bin)/";</p><p>    preg_match($regexp, $content, $result);</p><p>    var_dump($result);</p><p>    运行结果如下:</p><p>    array(4) { [0]=> string(8) "maweibin" [1]=> string(8) "maweibin" [2]=> string(5) "mawei" [3]=> string(2) "ma" } </p><p>?></p>
复制代码
通过结果,我们可以看到,第一个字表达式是“maweibin”,第二个字表达式是“mawei”,第三个字表达式是“ma”。


⑤正则表达式中的“$”陷阱!

在正则表达式中“$”符号,同托字节“^”一样是匹配一个位置的!但是“$”符号本身又有一些陷阱需要我们注意!
一般情况下,我们都认为“$”符号匹配就是一行中的最后一个位置!这个并没有错,但是不够详细!
其实$匹配的是这样一个位置,匹配\n前或单行字串的结束位置,单行字符串结尾什么都没有!举例说明:
  1. <p><?php</p><p>$str =<<<STR</p><p>the theory</p><p>my myselef</p><p>your yourselef</p><p>STR;</p><p>$reg = '/^([a-zA-Z]+)\s*\1[a-zA-Z]*$/m';</p><p>preg_match_all($reg, $str, $result);</p><p>var_dump($result);</p>
复制代码
运行的结果如下
  1. <p>array(2) { [0]=> array(1) { [0]=>string(14) "your yourselef" } [1]=> array(1) { [0]=> string(4)"your" } }</p><p>?></p>
复制代码
只有最后一个被匹配到了! 、
原因是这样的!在window中每换一行会有隐藏字符“\r\n”存在!

$匹配\n前或字串结尾(字符串结尾,比如单独一行的最后),\r 也是一个字符,且不在[a-zA-Z]范围!其实,我们只需要将正则改写为'/^([a-zA-Z]+)\s*\1[a-zA-Z] **\s**** $/m',这里只是加上了一个\s*用来匹配\r这个看不见的字符串!


⑥关于正则表达在多行匹配中的应用!

正则表达式大多数情况下是进行单行的匹配的!但是,有时候我们也需要进行多行的匹配,特别是在我们进行信息采集的时候,显得就尤为重要!
个人认为,在php中如果我们能够灵活的运用php的模式修饰符,那么多行匹配就没有什么问题了!所以多行匹配,个人认为就是重点对模式修饰符的学习!

(1)m(mutiline),加上了m修饰符号的主要作用是更改了托字节”^”和“$”的应用范围!
黑色箭头代表的是托字节”^”所匹配的位置,蓝色箭头是美元符号”%”所匹配的位置! 举例说明:

加上了m修饰符之后:

(2)S修饰如果设置了这个修饰符, 模式中的点号元字符匹配所有字符, 包含换行符. 如果没有这个 修饰符, 点号不匹配换行符.

(3)U(这个是大写的ungreedy:非贪婪)。

举例说明:

<a href=‘www.baidu.com'>百度</a><a href='www.google.com'谷歌</a>

正则如下:<a\s*href\s*=\s*’www\.baidu\.com’>.*</a>结果是把全部的字符串都匹配到了!其实,我们只需要加上U修饰符,这样,这样一旦成功匹配一次的话,正则就不会继续进行匹配了!

(4)i(个人认为应该是ingnore的意思),表示在匹配的时候忽略大小写。


⑦正则表达式是从左到右依次匹配的!这也是学习正则表达式要遵守的基本原则!
0 0
原创粉丝点击