今天看了一个网址http://deerchao.net/tutorials/regex/regex.htm#greedyandlazy ,关于正则 表达式写的蛮详细的,自己稍微总结了下:
元字符:
. 匹配除换行符以外的任意字符
/w 匹配字母或数字或下划线或汉字
/s 匹配任意的空白符
/d 匹配数字
/b 匹配单词的开始或结束
^ 匹配字符串的开始
$ 匹配字符串的结束
重复:
* 重复零次或更多次
+ 重复一次或更多次
? 重复零次或一次
{n} 重复n 次
{n,} 重复n 次或更多次
{n,m} 重复n 到m 次
字符转义: /
字符类: []
分枝条件: |
分组: ()
反义:
/W 匹配任意不是字母,数字,下划线,汉字的字符
/S 匹配任意不是空白符的字符
/D 匹配任意非数字的字符
/B 匹配不是单词开头或结束的位置
[^x] 匹配除了x 以外的任意字符
[^aeiou] 匹配除了aeiou 这几个字母以外的任意字符
后向引用:
默认情况下,每个分组会自动拥有一个组号 ,规则是:从左向右,以分组的左括号为标志,第一个出现的分组的组号为1 ,第二个为2
/b(/w+)/b/s+/1/b 可以用来匹配重复的单词 ,像go go , 或者kitty kitty
(?<Word>/w+) 或者 (?'Word'/w+) ) 对应 /k<Word>
分组0 对应整个正则表达式
实际上组号分配过程是要从左向右扫描两遍的:第一遍只给未命名组分配,第二遍只给命名组分配--因此所有命名组的组号都大于未命名的组号
常用分组语法
捕获
(exp) 匹配exp, 并捕获文本到自动命名的组里
(?<name>exp) 匹配exp, 并捕获文本到名称为name 的组里,也可以写成 (?'name'exp) (?:exp) 匹配exp, 不捕获匹配的文本,也不给此分组分配组号
零宽断言
断言用来声明一个应该为真的事实。正则表达式中只有当断言为真时才会继续进行匹配
(?=exp) 匹配exp 前面的位置
(?<=exp) 匹配exp 后面的位置
(?!exp) 匹配后面跟的不是exp 的位置
(?<!exp) 匹配前面不是exp 的位置
注释: (?#comment)
要包含注释的话,最好是启用 “ 忽略模式里的空白符 ” 选项
贪婪与懒惰
默认贪婪
*? 重复任意次,但尽可能少重复
+? 重复1 次或更多次,但尽可能少重复
?? 重复0 次或1 次,但尽可能少重复
{n,m}? 重复n 到m 次,但尽可能少重复
{n,}? 重复n 次以上,但尽可能少重复
正则表达式有另一条规则,比懒惰/贪婪规则的优先级更高: 最先开始的匹配拥有最高的优先权
.Net 中常用的正则表达式选项:
IgnoreCase( 忽略大小写) 匹配时不区分大小写。
Multiline( 多行模式) 更改^ 和$ 的 含义,使它们分别在任意一行的行首和行尾匹配,而不仅仅在整个字符串的开头和结尾匹配。( 在此模式下,$ 的 精确含意是: 匹配/n 之前的位置以及字符串结束前的位置.)
Singleline( 单行模式) 更改. 的含义,使它与每一个字符匹配(包括换行 符/n )。
IgnorePatternWhitespace( 忽略空白) 忽略表达式中的非转义空白并启用由# 标记的注释。
ExplicitCapture( 显式捕获) 仅捕获已被显式命名的组。
多行模式和单行模式之间没有任何关系,除了它们的名字比较相似
平衡组 / 递归匹配
(?'group') 把捕获的内容命名为group, 并压入堆栈(Stack)
(?'-group') 从堆栈上弹出最后压入堆栈的名为group 的捕获内容,如果堆栈本来为空,则本分组的匹配失败
(?(group)yes|no) 如果堆栈上存在以名为group 的捕获内容的话,继续匹配yes 部分的表达式,否则继续匹配no 部分
(?!) 零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败
匹配嵌套的<>内容:
< # 最外层的左括号
[^<>]* # 最外层的左括号后面的不是括号的内容
(
(
(?'Open'<) # 碰到了左括号,在黑板上写一个"Open"
[^<>]* # 匹配左括号后面的不是括号的内容
)+
(
(?'-Open'>) # 碰到了右括号,擦掉一个"Open"
[^<>]* # 匹配右括号后面不是括号的内容
)+
)*
(?(Open)(?!)) # 在遇到最外层的右括号前面,判断黑板上还有没有没擦掉的"Open" ;如果还有,则匹配失败
> # 最外层的右括号