正则表达式 - 负向前瞻

时间:2012-06-06 17:06:09

标签: regex negative-lookahead negative-lookbehind

我试图使用Perl的负前瞻正则表达式 从目标字符串中排除某些字符串。请给我你的建议。

我试图获取没有-sm,-sp或-sa的字符串。

REGEX:

hostname .+-(?!sm|sp|sa).+

INPUT

hostname 9amnbb-rp01c
hostname 9tlsys-eng-vm-r04-ra01c
hostname 9tlsys-eng-vm-r04-sa01c
hostname 9amnbb-sa01
hostname 9amnbb-aaa-sa01c

预期产出:

hostname 9amnbb-rp01c              - SELECTED
hostname 9tlsys-eng-vm-r04-ra01c   - SELECTED 
hostname 9tlsys-eng-vm-r04-sa01c
hostname 9amnbb-sa01
hostname 9amnbb-aaa-sa01c

但是,我在下面得到了这个实际的输出:

hostname 9amnbb-rp01c              - SELECTED
hostname 9tlsys-eng-vm-r04-ra01c   - SELECTED
hostname 9tlsys-eng-vm-r04-sa01c   - SELECTED
hostname 9amnbb-sa01
hostname 9amnbb-aaa-sa01c          - SELECTED

请帮帮我。

p.s。:我使用了Regex Coach 可视化我的结果。

2 个答案:

答案 0 :(得分:4)

移动前瞻内的.+-

hostname (?!.+-(?:sm|sp|sa)).+

Rubular:http://www.rubular.com/r/OuSwOLHhEy

当前表达式无法正常工作,因为当.+-超出前瞻时,它可以回溯直到前瞻不再导致正则表达式失败。例如,使用字符串hostname 9amnbb-aaa-sa01c和正则表达式hostname .+-(?!sm|sp|sa).+,第一个.+将匹配9amnbb,前瞻会看到aa作为接下来的两个字符并继续,第二个.+ woudl匹配aaa-sa01c

我当前正则表达式的替代方案如下:

hostname .+-(?!sm|sp|sa)[^-]+?$

这会阻止回溯,因为在前瞻之后不会发生-,使用非贪婪的?以便在多线全局模式下正常工作。

答案 1 :(得分:1)

以下内容通过您的测试用例:

hostname [^-]+(-(?!sm|sp|sa)[^-]+)+$

我认为这比F.J.的回答更容易阅读。

回答鲁迪:这个问题被视为一种排除案件的情况。这似乎很适合负面的先行。 :)