4

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

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

正则表达式:

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

输入

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

请帮我。

ps:我使用Regex Coach 来可视化我的结果。

4

2 回答 2

4

移动.+-前瞻的内部:

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

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

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

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

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

这将防止回溯,因为-在前瞻之后不会发生任何事情,因此使用了非贪婪?,以便在多行全局模式下正常工作。

于 2012-06-06T17:10:02.670 回答
1

以下通过了您的测试用例:

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

我认为它比 FJ 的答案更容易阅读。

回答鲁迪:这个问题是作为排除案例的情况提出的。这似乎很适合负前瞻。:)

于 2012-06-06T17:28:45.837 回答