Perl字符串模式匹配的负正则表达式

joe*_*joe 44 regex perl

我有这个正则表达式:

if($string =~ m/^(Clinton|[^Bush]|Reagan)/i)
  {print "$string\n"};
Run Code Online (Sandbox Code Playgroud)

我想与克林顿和里根相提并论,但不是布什.

它不起作用.

Stu*_*uck 133

你的正则表达式不起作用,因为[]定义了一个字符类,但你想要的是一个前瞻:

(?=) - Positive look ahead assertion foo(?=bar) matches foo when followed by bar
(?!) - Negative look ahead assertion foo(?!bar) matches foo when not followed by bar
(?<=) - Positive look behind assertion (?<=foo)bar matches bar when preceded by foo
(?<!) - Negative look behind assertion (?<!foo)bar matches bar when NOT preceded by foo
(?>) - Once-only subpatterns (?>\d+)bar Performance enhancing when bar not present
(?(x)) - Conditional subpatterns
(?(3)foo|fu)bar - Matches foo if 3rd subpattern has matched, fu if not
(?#) - Comment (?# Pattern does x y or z)
Run Code Online (Sandbox Code Playgroud)

所以试试:(?!bush)

  • +1用于总结先行运算符. (6认同)

Dem*_*nex 27

示范文本:

克林顿说,
布什用蜡笔
忘了里根

只是省略布什比赛:

$ perl -ne 'print if /^(Clinton|Reagan)/' textfile
Clinton said
Reagan forgot
Run Code Online (Sandbox Code Playgroud)

或者,如果您真的想指定:

$ perl -ne 'print if /^(?!Bush)(Clinton|Reagan)/' textfile
Clinton said
Reagan forgot
Run Code Online (Sandbox Code Playgroud)

  • 不知道为什么没有人提到它,但是`(?!Bush)`负面预测在'^(?!布什)(克林顿|里根)的模式中是完全多余的,因为"克林顿"和"里根"都不是以"布什"开头的`. (6认同)
  • 最好的样本文本 (3认同)

TLP*_*TLP 17

你的正则表达式如下:

/^         - if the line starts with
(          - start a capture group
Clinton|   - "Clinton" 
|          - or
[^Bush]    - Any single character except "B", "u", "s" or "h"
|          - or
Reagan)   - "Reagan". End capture group.
/i         - Make matches case-insensitive 
Run Code Online (Sandbox Code Playgroud)

所以,换句话说,正则表达式的中间部分正在搞砸你.由于它是一种"全能型"群体,它将允许任何不以"布什"中的任何大写或小写字母开头的行.例如,这些行符合您的正则表达式:

Our president, George Bush
In the news today, pigs can fly
012-3123 33
Run Code Online (Sandbox Code Playgroud)

如前所述,您要么做出否定的预测,要么只是制作两个正则表达式:

if( ($string =~ m/^(Clinton|Reagan)/i) and
    ($string !~ m/^Bush/i) ) {
   print "$string\n";
}
Run Code Online (Sandbox Code Playgroud)

正如mirod在评论中指出的那样,当使用插入符号(^)仅匹配行的开头时,第二次检查是非常不必要的,因为以"克林顿"或"里根"开头的行永远不会以"布什"开头.

但是,如果没有插入符号,它将是有效的.

  • @yair `^` 通常是指字符串的开头。但是,在字符类中,它确实否定了该类。因此,`[Bush]` 匹配 4 个字符 B、u、s 或 h 中的任何一个,而 `[^Bush]` 匹配除这 4 个字符之外的任何字符。 (3认同)