如何查找前面没有另一个特定单词的单词?

发布于 2024-08-13 09:28:49 字数 388 浏览 7 评论 0原文

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

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

foo is bar
hello bar

但不是这些

foobar
foo     bar

我尝试使用以下字符串

(?!<foo)bar

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

(?!<foo)\s*bar

匹配所有琴弦。

谢谢!

Which regular expression can I use to find all strings bar are not preceded by string foo? Having whitespace between the two is also illegal.

So the regex should match the following strings

foo is bar
hello bar

But not these

foobar
foo     bar

I've tried using the following

(?!<foo)bar

and it gets the work done for eliminating foobar, but I need to take care of the whitespace, and of course

(?!<foo)\s*bar

matches all the strings.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

謸气贵蔟 2024-08-20 09:28:49

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

您正在查找 $s =~ /bar/ 而不是 $s =~ /foo\s*bar/ 为 true 的字符串。

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

#!/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
Good: bar foo
Good: hello bar
Good: foo is bar
Good: barbar
Good: foo foo
Good: foo     bar
Good: foobar

Better to use other facilities of the programming language than to look too hard for a regex pattern.

You are looking for strings for which $s =~ /bar/ and not $s =~ /foo\s*bar/ is true.

The rest of the script below is just for testing.

#!/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";
    }
}

Output:

E:\srv\unur> j
Good: bar foo
Good: hello bar
Good: foo is bar
Good: barbar
Good: foo foo
Good: foo     bar
Good: foobar
〗斷ホ乔殘χμё〖 2024-08-20 09:28:49

给定一些测试用例,

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";
}

Given a few test cases

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

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

you could of course do by feeding the results of one pattern to another:

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

We can also do it with one:

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

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

But don't take my word for it.

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

for (@reject) {
  print +(/$pattern/ ? "FAIL" : "PASS"), ": $_\n";
}
木槿暧夏七纪年 2024-08-20 09:28:49
  (?!<foo)\s*bar

这将匹配空白

  (?!<foo)\s*bar

This will match the whitespace

寂寞陪衬 2024-08-20 09:28:49

php:

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

perl:

$string !~ /foo\s*bar/ && $string =~ /bar/

php:

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

perl:

$string !~ /foo\s*bar/ && $string =~ /bar/
若无相欠,怎会相见 2024-08-20 09:28:49

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

Windows:

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

Taking the information from earlier answers, wrapping as a perl one-liner, and making the regular expressions case-insensitive.

Windows:

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

With xx.txt containing:

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

The result of executing the one-liner at a command prompt:

foo is bar
hello bar
barbar
bar foo
barfoo
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文