我正在尝试使用 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
请帮助我。
p.s.:我使用了正则表达式教练可视化我的结果。
将.+-
移到前瞻内部:
hostname (?!.+-(?:sm|sp|sa)).+
卢布:http://www.rubular.com/r/OuSwOLHhEy
您当前的表达式无法正常工作,因为当.+-
在前瞻之外时,它可以回溯,直到前瞻不再导致正则表达式失败。 例如,对于字符串hostname 9amnbb-aaa-sa01c
和正则表达式hostname .+-(?!sm|sp|sa).+
,第一个.+
将匹配9amnbb
,前瞻会将aa
视为接下来的两个字符并继续,第二个.+
将匹配aaa-sa01c
。
我当前正则表达式的替代方案如下:
hostname .+-(?!sm|sp|sa)[^-]+?$
这将防止回溯,因为在前瞻之后不会发生-
,使用非贪婪?
,以便在多行全局模式下正常工作。
以下内容通过您的测试用例:
hostname [^-]+(-(?!sm|sp|sa)[^-]+)+$
我认为这比F.J.的回答更容易阅读。
回答鲁迪:这个问题是作为排除案件的情况提出的。这似乎很符合消极的展望。:)