百度空间 | 百度首页 
 
查看文章
 
正则表达式分组相关的知识2
2008-01-07 17:43
预搜索
(?=exp)
(?!exp)
(? <=exp)
(? <!exp)

下面的说明很容易让人头晕,不看也罢,我将以另一种方式对它们的作用和用法进行说明
(?=exp) 匹配exp前面的位置
(? <=exp) 匹配exp后面的位置
(?!exp) 匹配后面跟的不是exp的位置
(? <!exp) 匹配前面不是exp的位置

有的资料上翻译为零宽度断言,我习惯于预搜索这种叫法,前两个为正向预搜索,后两个为反向预搜索,当然还有其它翻译,其实都是一个意思,知道就行,不必在意

这四种表达式,它们与非捕获的相同之处在于,并不将匹配到的结果保存到捕获组,不同之处在于,非捕获组匹配到的内容,虽然不保存到捕获组,但却是在结果$0实实在在存在的,而以上四种表达式所匹配到的内容,一般来说,是不存在$0内的,所以说它们匹配的结果是零宽度的

更好的理解方式,是把它们作为附加条件,而不是正则表达式的组成部分

为了更好的说明,先说一下“缝隙”的概念,“缝隙”是零宽度的,它只是字符串中的一个位置,而不是实际的字符,如字符串“ab”,在“a”前面,“a”和“b”中间,还有“b”后面,分别有一个“缝隙”,也就是整个字符串有三个“缝隙”

(?=exp) 在所在“缝隙”的后面附加一个条件,也就是“缝隙”后面必须能够匹配exp的内容
(?!exp) 在所在“缝隙”的后面附加一个条件,也就是“缝隙”后面必须不能够匹配exp的内容
(? <=exp) 在所在“缝隙”的前面附加一个条件,也就是“缝隙”前面必须能够匹配exp的内容
(? <!exp) 在所在“缝隙”的前面附加一个条件,也就是“缝隙”前面必须不能够匹配exp的内容

举例说明如下:
<[^> ]*> 表达式任意html标签

附加一个条件
<(?!img)[^> ]*>
这个就表示除 <img...> 标签外的所有标签,看下实际例子
C# code
string test = "<p><a href=\"http://bbs.csdn.net\" title=\"床上等你\"><img src=\"http://bbs.csdn.net\\logo.jpg\">CSDN</a></p>"; MatchCollection mc = Regex.Matches(test, @"<(?!img)[^>]*>", RegexOptions .IgnoreCase); foreach(Match m in mc) { richTextBox1.Text += m.Value + "\n"; }

输出结果为:
<p>
<a href="http://bbs.csdn.net" title="床上等你">
</a>
</p>

这时再看一下 <(?!img)[^> ]*> 这个正则表达式
(?!img)所在的“缝隙”是“ <”和它后面的第一个字符之间的“缝隙”,它表示的意思就是,在这个“缝隙”的后面,不能是img,整个表达式的意思也就是不匹配 <img...> 标签

同理, <(?=img)[^> ]*> 表示只匹配 <img...> 标签
C# code
string test = "<p><a href=\"http://bbs.csdn.net\" title=\"床上等你\"><img src=\"http://bbs.csdn.net\\logo.jpg\">CSDN</a></p>"; MatchCollection mc = Regex.Matches(test, @"<(?=img)[^>]*>", RegexOptions.IgnoreCase); foreach(Match m in mc) { MessageBox.Show(m.Value); }

输出:
<img src="http://bbs.csdn.net\logo.jpg">

(? <= <a[^> ]*> ) <img[^> ]*> 表示只匹配前面为 <a...> 标签的 <img...> 标签
C# code
string test = "<p><a href=\"http://bbs.csdn.net\" title=\"床上等你\"><img src=\"http://bbs.csdn.net\\logo.jpg\">CSDN</a></p><img src=\"http://bbs.csdn.net\\home.jpg\">"; MatchCollection mc = Regex.Matches(test, @"(?<=<a[^>]*>)<img[^>]*>", RegexOptions.IgnoreCase); foreach(Match m in mc) { MessageBox.Show(m.Value); }

输出:
<img src="http://bbs.csdn.net\logo.jpg">

(? <! <a[^> ]*> ) <img[^> ]*> 表示只匹配前面不为 <a...> 标签的 <img...> 标签 
C# code
string test = "<p><a href=\"http://bbs.csdn.net\" title=\"床上等你\"><img src=\"http://bbs.csdn.net\\logo.jpg\">CSDN</a></p><img src=\"http://bbs.csdn.net\\home.jpg\">"; MatchCollection mc = Regex.Matches(test, @"(?<!<a[^>]*>)<img[^>]*>", RegexOptions.IgnoreCase); foreach(Match m in mc) { MessageBox.Show(m.Value); }

输出:
<img src="http://bbs.csdn.net\home.jpg">

以上面的这个(? <= <a[^> ]*> ) <img[^> ]*> 为例,表达式中虽然有(? <= <a[^> ]*> ),但是在结果m.Value中并不存在它匹配到的内容 <a href="http://bbs.csdn.net" title="床上等你"> ,所以说它是零宽度的,只是作为一个附加条件存在

类别:c#,sql | 添加到搜藏 | 浏览() | 评论 (0)
 
最近读者:
 
网友评论:
发表评论:
姓 名:
网址或邮箱: (选填)
内 容:
验证码: 请点击后输入四位验证码,字母不区分大小写
      

     

©2009 Baidu