0

我有这个日志:

The Foo bar, and Bar foo needs to Foo 
The Bar of Bar foo Bar Foo Foo
Bar bar The Bar of Foo other Foo Bar

我想创建一个只选择不是 Foo 或 Bar 的单词的 perl 表达式。结果日志必须是:

The bar, and foo needs to
The of foo
The of other

我有这个:

^(Foo|Bar)

但它不起作用。

4

2 回答 2

3

如果您尝试从字符串中删除值,则可以进行替换:

my $str = <<EOS;
    The Foo bar, and Bar foo needs to Foo
    The Bar of Bar foo Bar Foo Foo
    Bar bar The Bar of Foo other Foo Bar
EOS
$str =~ s/(?:Foo|Bar) ?//g;
print $str;

>>>The bar, and foo needs to
   The of foo
   bar The of other

请注意,最后一个“条”(小写)仍在其中;我假设这是您帖子中的错误。

于 2013-08-31T04:54:11.603 回答
3

如果我正确理解评论,您想要的是捕获所有不是Fooor的单词,Bar然后大概以某种方式打印它们。这将是做这种事情的一种方法:

/(?<!\S)(?!Foo|Bar)\S+(?!\S)/g

它没有看起来那么复杂,这是带注释的版本:

/
    (?<!\S)            # match cannot be preceded by non-whitespace
    (?!Foo|Bar)(\S+)   # capture non-whitespace that is not Foo|Bar
    (?!\S)             # match cannot be followed by non-whitespace
/gx                    # match globally and ignore whitespace in regex

请注意,/x它就在那里,所以我可以在正则表达式中使用注释和换行符。

这个正则表达式的开始和结束部分是我们的边界锚。我们使用这些来确保我们不会得到部分匹配。它们是否定的环视断言,是更简单的\b词边界断言的替代品。但是这里不可能使用\b,因为你的字符串中有一个逗号字符。我们使用(?!\S)代替的原因\s是,虽然它们都匹配空格,但后者不匹配字符串的开始/结束。

因为我们已经向自己保证我们不能得到部分匹配,所以我们现在可以在我们的锚点内使用一个简单的交替与另一个否定的前瞻断言。即(?!Foo|Bar)。如果不匹配,我们用 捕获字符串(\S+)

这是我为这个问题创建的测试用例:

perl -nlwe 'push @a, [/(?<!\S)(?!Foo|Bar)(\S+)(?!\S)/g] }{ print "@$_" for @a'
The Foo bar, and Bar foo needs to Foo
The Bar of Bar foo Bar Foo Foo
Bar bar The Bar of Foo other Foo Bar
^Z
The bar, and foo needs to
The of foo
bar The of other

这使用我们的正则表达式从$_(输入)捕获字符串并将它们推送到@a数组引用内的数组中。输入完成后(在 eskimo operator 之后}{),我们打印插入的数组引用以添加空格。"@$_"相当于join " ", @$_在这种情况下。

于 2013-08-31T12:16:22.193 回答