寻求正则表达式帮助。我想设计一个可以匹配"foo" 或 "bar", 但不是同时含有"foo" 和 "bar"的字符串表达式。
如果我使用类似的表达式...
/((foo)|(bar))/
它将匹配 "foobar"。但这不是我要找的内容。那么,我该如何使正则表达式仅在其中一个条件存在时匹配?
谢谢!
寻求正则表达式帮助。我想设计一个可以匹配"foo" 或 "bar", 但不是同时含有"foo" 和 "bar"的字符串表达式。
如果我使用类似的表达式...
/((foo)|(bar))/
它将匹配 "foobar"。但这不是我要找的内容。那么,我该如何使正则表达式仅在其中一个条件存在时匹配?
谢谢!
{1}
,这是什么意思? - oriadamfoo
或 bar
应该只被匹配一次。 - Karl{1}
,因为它表示应该重复1次。只需要/^(foo|bar)$/
就足够了。这个正则表达式之所以有效是因为你使用了^
和$
,与重复无关。 - chharvey使用负向零宽断言
(?<!foo|bar)(foo|bar)(?!foo|bar)
这将匹配不紧接着或不紧随“foo”或“bar”的“foo”或“bar”,我认为这正是您想要的。
从您的问题或示例中无法确定您要匹配的字符串是否可以包含其他标记:“foocuzbar”。如果是这样,这个模式将无法工作。
以下是测试用例的结果(“true”表示在输入中找到了该模式):
foo: true
bar: true
foofoo: false
barfoo: false
foobarfoo: false
barbar: false
barfoofoo: false
你可以用一条正则表达式完成这个任务,但出于可读性的考虑,我建议你做如下处理...
(/foo/ and not /bar/) || (/bar/ and not /foo/)
/^(foo|bar)$/
^ = mark start of string (or line)
$ = mark end of string (or line)
这将接受 'foo' 和 'bar' 和 'foo bar' 和 'bar-foo',但不接受 'foobar'、'blafoo' 和 'blabar':
/\b(foo|bar)\b/
\b = mark word boundry
@matches = ($value =~ /(foo|bar)/g) # @matches now hold all foos or bars present
if (scalar @matches == 1) { # exactly one match found
...
}
/foo/ xor /bar/
但是你的评论:
匹配: "foo", "bar" 非匹配: "foofoo" "barfoo" "foobarfoo" "barbar" "barfoofoo"
表明你实际上并不是在寻找排他或。你的意思是“/foo|bar/
是否只匹配一次?”
my $matches = 0;
while (/foo|bar/g) {
last if ++$matches > 1;
}
my $ok = ($matches == 1)
我知道这是一个晚期的条目,但只是为了帮助其他可能正在寻找的人:
(/b(?:(?:(?!foo)bar)|(?:(?!bar)foo))/b)
我认为这不能通过一个正则表达式完成。边界可能有用也可能无用,这取决于你匹配的内容。
我会分别使用每个正则表达式进行匹配,并对结果执行异或操作。
foo = re.search("foo", str) != None
bar = re.search("bar", str) != None
if foo ^ bar:
# do someting...
\w
,你可以使用\b
或\B
来检查边界。这将匹配 " foo " 或 " bar ",所以显然你也必须替换空格,以防万一。(假设你要替换任何东西。)/\s((foo)|(bar))\s/