我有以下示例
“Foo告诉酒吧酒吧喜欢土豆。酒吧告诉foo酒吧没有 像马铃薯。“
我想要马铃薯和之前出现的bar之间的子串。所以在这个例子中,我想要“酒吧喜欢土豆”,并且也希望“酒吧不喜欢土豆”。我如何通过一个正则表达式实现这一目标?我知道如果我应用两个单独的正则表达式我可以得到结果但我想知道这是否可能只有一个正则表达式。
谢谢, RG
答案 0 :(得分:3)
好谜语。它可以解决,只是不是很好的方式:
echo "Foo tells bar that bar likes potato. Bar tells foo that bar does not like potato." | \
pcregrep -o '\bbar\s+(?:(?:(?!bar\b)\w+)\s+)*?potato\b'
外部(?:...)
匹配单词后跟空格。内在的一个确保所说的单词不是bar
。
答案 1 :(得分:1)
在Python
:
>>> import re
>>> s = "Foo tells bar that bar likes potato. Bar tells foo that bar does not like potato."
>>> re.findall('bar (?:(?! bar ).)+? potato', s)
['bar likes potato', 'bar does not like potato']
答案 2 :(得分:0)
有可能,如下面的perl片段所示:
use strict;
use warnings;
my $str
= "Foo tells bar that bar likes potato. "
. "Bar tells foo that bar does not like potato."
;
while ($str =~ m/( bar (?: [^b] | b[^a] | ba[^r] )*? potato )/xmsg) {
print STDOUT "$1\n";
}
*?
是一个非贪婪的量词(匹配0次或更多次,而非贪婪;请参阅http://perldoc.perl.org/perlre.html处的量词)
请注意,替代[^b] | b[^a] | ba[^r]
是互斥的。这本书"掌握正则表达式"如果您想要了解有关此类构造的更多信息,那么(http://regex.info/)非常有启发性。