正则表达式基础知识

1、 正则表达式元字符

. 匹配除换行符以外的任意字符
\w 匹配字母或数字或下划线或汉字
\s 匹配任意空白字符
\d \d匹配数字
\b 匹配单词的开始或结束
$ 匹配字符串的结束
[abcd] 匹配字符’a’,’b’,’c’,’d’字符

 

2、 正则表达式的反义
\W 匹配任意不是字母或数字或下划线或汉字
\S 匹配不是空白字符
\D 匹配非数字的字符
\B 匹配不是单词开始或结束的位置
[^X] 除X以外的任意字符
[^aeiou] 匹配字符串的结束
[abcd] 匹配除aeiou字母以外的其它任意字符

 

3、 重复

* 重复0次或更多次
+ 重复一次或更多次

? 重复0次或一次
{n} 重复n次
{n,} 重复n次或更多次
{n,m} 重复n到m次

 

4、分支条件 |

 0\d{2}-\d{8}|0\d{3}-\d{7}这个表达式能匹配两种以连字号分隔的电话号码:一种是三位区号,8位本地号(如010-12345678),一种是4位区号,7位本地号(0376-2233445)。

 

5、贪婪与懒惰

*? 重复任意次,但尽可能少重复
+? 重复1次或更多次,但尽可能少重复

?? 重复0次或1次,但尽可能少重复

{n,m}? 重复n到m次,但尽可能少重复

{n,}? 重复n次以上,但尽可能少重复
    举例1:表达式 "<td>(.*)</td>" 与字符串 "<td><p>aa</p></td> <td><p>bb</p></td>" 匹配时,匹配的结果是:成功;匹配到的内容是 "<td><p>aa</p></td> <td><p>bb</p></td>" 整个字符串, 表达式中的 "</td>" 将与字符串中最后一个 "</td>" 匹配。
    举例2:相比之下,表达式 "<td>(.*?)</td>" 匹配举例1中同样的字符串时,将只得到 "<td><p>aa</p></td>", 再次匹配下一个时,可以得到第二个 "<td><p>bb</p></td>"。

 

6、处理选项

Ignorecase 默认情况下,表达式中的字母是要区分大小写的。配置为 Ignorecase 可使匹配时不区分大小写。有的表达式引擎,把 "大小写" 概念延伸至 UNICODE 范围的大小写。

Singleline 默认情况下,小数点 "." 匹配除了换行符(\n)以外的字符。配置为 Singleline 可使小数点可匹配包括换行符在内的所有字符。

Multiline 默认情况下,表达式 "^" 和 "$" 只匹配字符串的开始 ① 和结尾 ④ 位置。如:
①xxxxxxxxx②\n
③xxxxxxxxx④
配置为 Multiline 可以使 "^" 匹配 ① 外,还可以匹配换行符之后,下一行开始前 ③ 的位置,使 "$" 匹配 ④ 外,还可以匹配换行符之前,一行结束 ② 的位置。

Global 主要在将表达式用来替换时起作用,配置为 Global 表示替换所有的匹配。
ExplicitCapture 仅捕获已被显式命名的组。
ECMAScript(JavaScript兼容模式) 使表达式的行为与它在JavaScript里的行为一致。
RightToLeft(从右向左查找) 匹配从右向左而不是从左向右进行。

 

7、反向引用 \1, \2...
    表达式在匹配时,表达式引擎会将小括号 "( )" 包含的表达式所匹配到的字符串记录下来。在获取匹配结果的时候,小括号包含的表达式所匹配到的字符串可以单独获取。这一点,在前面的举例中,已经多次展示了。在实际应用场合中,当用某种边界来查找,而所要获取的内容又不包含边界时,必须使用小括号来指定所要的范围。比如前面的 "<td>(.*?)</td>"。
    其实,"小括号包含的表达式所匹配到的字符串" 不仅是在匹配结束后才可以使用,在匹配过程中也可以使用。表达式后边的部分,可以引用前面 "括号内的子匹配已经匹配到的字符串"。引用方法是 "\" 加上一个数字。"\1" 引用第1对括号内匹配到的字符串,"\2" 引用第2对括号内匹配到的字符串……以此类推,如果一对括号内包含另一对括号,则外层的括号先排序号。换句话说,哪一对的左括号 "(" 在前,那这一对就先排序号。
    举例如下:
    举例1:表达式 "('|")(.*?)(\1)" 在匹配 " 'Hello', "World" " 时,匹配结果是:成功;匹配到的内容是:" 'Hello' "。再次匹配下一个时,可以匹配到 " "World" "。
    举例2:表达式 "(\w)\1{4,}" 在匹配 "aa bbbb abcdefg ccccc 111121111 999999999" 时,匹配结果是:成功;匹配到的内容是 "ccccc"。再次匹配下一个时,将得到 999999999。这个表达式要求 "\w" 范围的字符至少重复5次,注意与 "\w{5,}" 之间的区别。
    举例3:表达式 "<(\w+)\s*(\w+(=('|").*?\4)?\s*)*>.*?</\1>" 在匹配 "<td id='td1' style="bgcolor:white"></td>" 时,匹配结果是成功。如果 "<td>" 与 "</td>" 不配对,则会匹配失败;如果改成其他配对,也可以匹配成功。


8、其它通用规则
8.1 表达式中,可以使用 "\xXX" 和 "\uXXXX" 表示一个字符("X" 表示一个十六进制数)
  \xXX 编号在 0 ~ 255 范围的字符,比如:空格可以使用 "\x20" 表示


  \uXXXX 任何字符可以使用 "\u" 再加上其编号的4位十六进制数表示,比如:"\u4E2D"
8.2在表达式中有特殊意义,需要添加 "\" 才能匹配该字符本身的字符汇总
^ 匹配输入字符串的开始位置。要匹配 "^" 字符本身,请使用 "\^"
$ 匹配输入字符串的结尾位置。要匹配 "$" 字符本身,请使用 "\$"
( ) 标记一个子表达式的开始和结束位置。要匹配小括号,请使用 "\(" 和 "\)"
[ ] 用来自定义能够匹配 '多种字符' 的表达式。要匹配中括号,请使用 "\[" 和 "\]"
{ } 修饰匹配次数的符号。要匹配大括号,请使用 "\{" 和 "\}"
. 匹配除了换行符(\n)以外的任意一个字符。要匹配小数点本身,请使用 "\."
? 修饰匹配次数为 0 次或 1 次。要匹配 "?" 字符本身,请使用 "\?"
+ 修饰匹配次数为至少 1 次。要匹配 "+" 字符本身,请使用 "\+"
* 修饰匹配次数为 0 次或任意次。要匹配 "*" 字符本身,请使用 "\*"
| 左右两边表达式之间 "或" 关系。匹配 "|" 本身,请使用 "\|"


8.3 如果要要求表达式所匹配的内容是整个字符串,而不是从字符串中找一部分,那么可以在表达式的首尾使用 "^" 和 "$",比如:"^\d+$" 要求整个字符串只有数字。


8.4如果要求匹配的内容是一个完整的单词,而不会是单词的一部分,那么在表达式首尾使用 "\b",比如:使用 "\b(if|while|else|void|int……)\b" 来匹配程序中的关键字。


8.5表达式不要匹配空字符串。否则会一直得到匹配成功,而结果什么都没有匹配到。比如:准备写一个匹配 "123"、"123."、"123.5"、".5" 这几种形式的表达式时,整数、小数点、小数数字都可以省略,但是不要将表达式写成:"\d*\.?\d*",因为如果什么都没有,这个表达式也可以匹配成功。更好的写法是:"\d+\.?\d*|\.\d+"。


8.6能匹配空字符串的子匹配不要循环无限次。如果括号内的子表达式中的每一部分都可以匹配 0 次,而这个括号整体又可以匹配无限次,那么情况可能比上一条所说的更严重,匹配过程中可能死循环。虽然现在有些正则表达式引擎已经通过办法避免了这种情况出现死循环了,比如 .NET 的正则表达式,但是我们仍然应该尽量避免出现这种情况。如果我们在写表达式时遇到了死循环,也可以从这一点入手,查找一下是否是本条所说的原因。


8.7或 "|" 的左右两边,对某个字符最好只有一边可以匹配,这样,不会因为 "|" 两边的表达式因为交换位置而有所不同。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值