码迷,mamicode.com
首页 > 其他好文 > 详细

regex_note

时间:2016-02-26 13:49:06      阅读:162      评论:0      收藏:0      [点我收藏+]

标签:

# 正则表达式

# 元字符
    对于字符串"DEF",在正则中视为包含3个字符"D","E","F"和4个位置0-3,"DEF"= 0D1E2F3.
    如果子表达式匹配到东西,而不是一个位置,并最终保存到匹配的结果中.这样的就称为占有字符.占有字符是互斥的,即一个字符,同一时间只能由一个子表达式匹配。
    而只匹配一个位置,或匹配的内容并不保存到匹配结果中,这就称为零宽度.零宽度是非互斥的,即一个位置,可以同时有多个零宽度的子表达式匹配.

# 元字符  描述
  \b      匹配单词的开始或结束
  \w      匹配字母或数字或下划线或汉字
  \s      匹配任意空白符,包括空格,TAB,换行符等
  \d      匹配任意数字
  .       匹配出换行符外任意字符
  ^       匹配字符串的开始
  $       匹配字符串的结束

# 字符转义
    如果想查找元字符本身,需要使用‘\‘来转义.如: \.

# 重复    描述
  *       重复0次或多次
  +       重复1次或多次
  ?       重复0次或1次
  {n}     重复n次
  {n,}    重复n次或更多次
  {n,m}   重复n到m次

    例如: \d{5,12}  匹配了5到12位的连续数字.

# 字符类  描述
  []      方括号中列出匹配字符的集合

    例如: [0-9] 表示匹配一位数字

# 分支条件描述
  |       符号‘|‘把不同规则隔开

    例如: \d{5}-\d{4}|\d{5} 可以匹配连字符间隔的9位数字或5位数字.值得一提的是要注意各个条件的顺序.因为匹配分枝条件时,会从左到右的匹配,如果满足了某个分支,就不会再管其它条件了.

# 分组    描述
  ()      括号里的子表达式被作为一组

    例如: (\d{1,3}\.){3} 匹配出现3次的(\d{1,3}\.)
# 反意    描述
  \W      匹配任意不是字母,数字,下划线,汉字的字符
  \S      匹配任意不是空白符的字符
  \D      匹配任意不是数字的字符
  \B      匹配任意不是单词开头或结束的位置
  [^x]    匹配除了x以外的任意字符
  [^aeio] 匹配除了aeio这几个字符的任意字符

# 后向引用
    使用小括号指定一个子表达式后,匹配到的内容可以用于进一步处理,默认情况下,每个分组会自动拥有一个组号,依次为1,2,3... 另外,分组0对应整个正则表达式.
    使用\1代表分组1匹配的文本.如: \b(\w+)\b\s+\1\b 这可以用来匹配重复的单词.
 语法          描述
 (exp)         匹配exp,并捕获文本到自动命名的组里
 (?<name>exp)  匹配exp,并捕获文本到名为name的组里,也可以写成(?‘name‘exp)
               调用有名字的组可以使用\k<name>
 (?exp)        匹配exp,不捕获匹配的文本,也不给此分组分配组号

# 注释
 语法          描述
 (?#comment)   这种类型的分组不对正则表达式的处理产生影响,用于提供注释

    要包含注释的话,最好是启用“忽略模式里的空白符”选项,这样在编写表达式时能任意的添加空格,Tab,换行,而实际使用时这些都将被忽略。启用这个选项后,在#后面到这一行结束的所有文本都将被当成注释忽略掉。
    例子:
(?<=           #断言要匹配的文本的前缀     
<(\w+)>        #查找尖括号括起来的字母或数字(即HTML/XML标签)
)              #前缀结束
.*             #匹配任意文本
(?=            #断言要匹配的文本的后缀
<\/\1>         #查找尖括号括起来的内容:前面是一个"/",后面是先前捕获的标签
)              #后缀结束

# 零宽断言
    零宽断言: 用于指定一个位置,并且这个位置满足一定的条件(即断言).
 语法          描述
 (?=exp)       匹配exp前面的位置,即断言自身后面能匹配表达式exp
 (?<=exp)      匹配exp后面的位置,即断言自身前面能匹配表达式exp
 (?!exp)       匹配后面不是exp的位置
 (?<!exp)      匹配前面不是exp的位置

# 贪婪和懒惰
    当正则表达式中包含能接受重复的限定符时,通常的行为是匹配尽可能多的字符.如a.*b,将会匹配最长的以a开始,以b结束的字符串,若搜索aabab时,它会匹配整个字符串aabab.这是贪婪匹配.
    有时,我们需要懒惰匹配,就是匹配尽可能少的字符.只要在重复表达式后面加上一个问号.如: a.*?b 匹配以a开始,以b结束的字符串.若搜索aabab,它会匹配aab和ab.

常用懒惰限定符
*?, +?, ??, {n,m}?, {n,}?

# 正则表示式处理选项
 忽略大小写   匹配时不去分大小写
 多行模式     更改^和$的含义,使它们分别匹配每行的行首和行尾
              而不是仅在字符串的开始和结束匹配
 单行模式     更改.的含义,使它也能匹配换行符\n
 忽略空白     忽略表达式中的非转义空白,并启用由#标记的注释
 显式捕获     仅匹配已被显式命名的组

# 平衡组/递归匹配
应用场景:(100*(50+15)) 或  (5/(3+2)))
递归配对用于解决括号配对问题.


    (?‘group‘) 把捕获的内容命名为group,并压入堆栈(Stack)
    (?‘-group‘) 从堆栈上弹出最后压入堆栈的名为group的捕获内容,如果堆栈本来为空,则本分组的匹配失败
    (?(group)yes|no) 如果堆栈上存在以名为group的捕获内容的话,继续匹配yes部分的表达式,否则继续匹配no部分
    (?!) 零宽负向先行断言,由于没有后缀表达式,试图匹配总是失败

我们需要做的是每碰到了左括号,就在压入一个"Open",每碰到一个右括号,就弹出一个,到了最后就看看堆栈是否为空--如果不为空那就证明左括号比右括号多,那匹配就应该失败。正则表达式引擎会进行回溯(放弃最前面或最后面的一些字符),尽量使整个表达式得到匹配。
< #最外层的左括号 [^<>]* #最外层的左括号后面的不是括号的内容
( ( (?‘Open‘<) #碰到了左括号,在黑板上写一个"Open"
[^<>]* #匹配左括号后面的不是括号的内容 )+ ( (?‘-Open‘>) #碰到了右括号,擦掉一个"Open"
[^<>]* #匹配右括号后面不是括号的内容 )+ )* (?(Open)(?!)) #在遇到最外层的右括号前面,判断黑板上还有没有没擦掉的"Open";如果还有,则匹配失败 > #最外层的右括号

平衡组的一个最常见的应用就是匹配HTML,下面这个例子可以匹配嵌套的<div>标签:<div[^>]*>[^<>]*(((?‘Open‘<div[^>]*>)[^<>]*)+((?‘-Open‘</div>)[^<>]*)+)*(?(Open)(?!))</div>.

regex_note

标签:

原文地址:http://www.cnblogs.com/ct-blog/p/5219902.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!