public static void man

_hope is a good thing

正则表达式必知必会 5

| Comments

在正则表达式里嵌入条件

顾名思义,我们可以在正则表达式里插入某些条件,这些条件可以作为另外一些正则表达式被执行的条件.

?:嵌入条件的语法使用?来定义,嵌入条件不外乎两种情况:

  • 根据一个回溯引用来进行条件处理
  • 根据一个前后查找来进行条件处理

回溯引用条件

回溯引用条件只在前一个子表达式成功匹配情况下才允许使用.回溯引用条件的语法是(?(backreference)true-regex).即如果回溯引用存在才指向后面的regex.

例子:

需要把一个文本里面的所有<IMG>标签找出来,如果某个标签是个链接(被包含在<a>和</a>之间),需要把整个链接标签匹配出来.

#

文本:

<a href=“/home”><img src=“/home/abc.png”></a>

<img src=“/Documents/cat.png”>

<H1>title something</H1>

<a href=“/home”><img src=“/home/ppl.png”></a>

<img src=“/Documents/dog.png”>

<H2>title haha something</H2>

正则表达式: (<[Aa]\s+[^>]+>\s*)?<[Ii][Mm][Gg]\s+[^>]+>(?(1)\s*</[Aa]>)

结果:

<a href=“/home”><img src=“/home/abc.png”></a>

<img src=“/Documents/cat.png”>

<a href=“/home”><img src=“/home/ppl.png”></a>

<img src=“/Documents/dog.png”>

这里的正则表达式第一部分是(<[Aa]\s+[\^>]+>\s*)?,它是一个子表达式用来匹配<a>或者<A>.第二部分\<[Ii][Mm][Gg]\s+[\^>]+>用来匹配一个(大小写均可).第三部分(?(1)\s\*</[Aa]>)是一个回溯引用条件 — ?(1)的意思是如果第一个回溯引用存在,则使用\s\*</[Aa]>继续进行匹配.

回溯引用条件还有否定表达式,即在条件不满足的情况下才被执行,语法是(?(backreference)true-regex|false-regex)

#

文本:

123-456-2712

(123)442-9812

(123)-221-9123

(314-221-0812

1234567890

123 456 7890

正则表达式: (()?\d{3}(?(1))|–)\d{3}–\d{4}

结果: 123-456-2712 (123)442-9812

这个正则表达式分为几个部分,首先是(\()?用来匹配左括号,接着是d{3}匹配3个数字,然后是一个回溯引用条件(?(1)\)|-),它表示如果第一个回溯引用(左括号)存在,就执行\),即匹配右括号,如果不存在|就匹配破折号-.最后匹配3个和4个连续的数字.

前后查找条件

定义一个前后查找条件和回溯引用条件大同小异,只需要把回溯引用(括号里的回溯引用编号)替换为一个完整的前后查找表达式就行了.

#

文本:

11111

22222

33333-

44444-1123

正则表达式: \d{5}(-d{4})?

结果:

11111

22222

33333-

44444-1123

这并不是我们想要的效果,因为33333-被包含了进来.这时就是前后查找条件大显身手的时候.

#

文本:

11111

22222

33333-

44444-1123

正则表达式: \d{5}(?(?=–)-d{4})

结果:

11111

22222

44444-1123

\d{5}匹配前五个数字,接下来的(?(?=-)-d{4})使用了向前查找条件,它表示在-存在的情况下才继续向后匹配(匹配-\d{4}).这样就排除了33333-这种情况.

Comments