在下面的例子中,负面的后视是如何运作的?

时间:2013-07-31 15:13:28

标签: regex perl

为什么在数据(d)上应用正则表达式(rx)给出输出(o)?
正则表达式(rx):

s/(?<!\#include)[\s]*\<[\s]*([^\s\>]*)[\s]*\>/\<$1\>/g

数据(d):

#include  <a.h>  // 2 spaces after e

输出(o):

#include <a.h>  // 1 space is still there

预期输出为:

#include<a.h>  // no space after include

3 个答案:

答案 0 :(得分:6)

当你通过两个空格中的第一个时,条件(?<!\#include)为真,因此匹配从那里开始。

#include  <a.h>
         ^^^^^^- matched by your regex.

这意味着您的替换操作不会移除空间。

如果您使用positive lookbehind assertion,则可获得所需的结果:

s/(?<=#include)\s*<\s*([^\s>]*)\s*>/<$1>/g;

可以重写以使用more efficient \K

s/#include\K\s*<\s*([^\s>]*)\s*>/<$1>/g;

答案 1 :(得分:2)

?<!\#include)[\s]是一个空格,前面没有#include#include <a.h>中的第一个空格前面紧跟#include,因此不匹配。第二个不是(它前面是另一个空格),所以这就是比赛开始的地方。

答案 2 :(得分:0)

作为旁注,你可以使用这种不使用外观的模式:

s/(?:#include\K|\G)(?:\s+|(<|[^\s><]+))/$1/g

模式细节:

(?:              # open a non capturing group
    #include\K   # match "#include" and reset it from the match result
  |              # OR
    \G           # a contiguous match
)                # close the non capturing group
(?:          
    \s+          # white characters (spaces or tabs here) 
  |              # OR
    (            # capturing group
        <
      |
        [^\s><]+ # content inside brackets except spaces (and brackets)
    )
)

搜索在结束括号处停止,因为它没有在模式中描述,因为在下一个#include之前没有更多的连续匹配。