7

我可以使用哪个正则表达式来查找所有字符串bar前面没有字符串foo?两者之间有空格也是非法的。

所以正则表达式应该匹配以下字符串

foo is bar
hello bar

但不是这些

foobar
foo     bar

我试过使用以下

(?!<foo)bar

它完成了消除的工作foobar,但我需要处理空白,当然

(?!<foo)\s*bar

匹配所有字符串。

谢谢!

4

5 回答 5

4

最好使用编程语言的其他工具,而不是过于努力地寻找正则表达式模式。

您正在寻找$s =~ /bar/ and not $s =~ /foo\s*bar/正确的字符串。

以下脚本的其余部分仅用于测试。

#!/usr/bin/perl

use strict; use warnings;

my %strings = (
    'foo is bar'  => 1,
    'hello bar'   => 1,
    'foobar'      => 0,
    'foo     bar' => 0,
    'barbar'      => 1,
    'bar foo'     => 1,
    'foo foo'     => 0,
);

my @accept = grep { $strings{$_} } keys %strings;
my @reject = grep { not $strings{$_} } keys %strings;

for my $s ( @accept ) {
    if ( $s =~ /bar/ and not $s =~ /foo\s*bar/ ) {
        print "Good: $s\n";
    }
    else {
        print "Bad : $s\n";
    }
}

for my $s ( @reject ) {
    if ( $s =~ /bar/ and not $s =~ /foo\s*bar/ ) {
        print "Bad : $s\n";
    }
    else {
        print "Good: $s\n";
    }
}

输出:

E:\srv\unur> j
好:吧台
好:你好吧
好: foo 是酒吧
好:barbar
好:foo foo
好:富吧
好:foobar
于 2009-12-02T20:57:23.467 回答
2

给定几个测试用例

my @match = (
  "foo is bar",
  "hello bar",
);

my @reject = (
  "foobar",
  "foo     bar",
);

您当然可以通过将一种模式的结果提供给另一种模式来实现:

my @control = grep !/foo\s*bar/, grep /bar/ => @match, @reject;

我们也可以这样做:

my $nofoo = qr/
  (      [^f] |
    f  (?! o) |
    fo (?! o  \s* bar)
  )*
/x;

my $pattern = qr/^ $nofoo bar /x;

但不要相信我的话。

for (@match) {
  print +(/$pattern/ ? "PASS" : "FAIL"), ": $_\n";
}

for (@reject) {
  print +(/$pattern/ ? "FAIL" : "PASS"), ": $_\n";
}
于 2009-12-02T20:51:49.883 回答
0
  (?!<foo)\s*bar

这将匹配空格

于 2009-12-02T20:42:47.273 回答
0

从早期答案中获取信息,包装为 perl 单行,并使正则表达式不区分大小写。

视窗:

perl -lne "print $_ if $_ !~ m/foo\s*bar/i && $_ =~ m/bar/i;" c:\temp\xx.txt

Linux:

perl -lne 'print $_ if $_ !~ m/foo\s*bar/i && $_ =~ m/bar/i;' /tmp/xx.txt

xx.txt 包含:

foo is bar
hello bar
foobar
foo     bar
barbar
bar foo
barfoo
foo foo

在命令提示符下执行单行的结果:

foo is bar
hello bar
barbar
bar foo
barfoo
于 2013-05-07T23:20:00.357 回答
0

php:

!preg_match(/foo\s*bar/,$string) && preg_match(/bar/,$string)

perl:

$string !~ /foo\s*bar/ && $string =~ /bar/
于 2009-12-02T20:46:58.880 回答