Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Regex 正则表达式中的异或_Regex_Xor - Fatal编程技术网

Regex 正则表达式中的异或

Regex 正则表达式中的异或,regex,xor,Regex,Xor,正在寻找一些正则表达式帮助。 我想设计一个表达式,使字符串与“foo”或“bar”匹配,但不能同时与“foo”和“bar”匹配 如果我做了像 /((foo)|(bar))/ (/foo/ and not /bar/) || (/bar/ and not /foo/) 它将匹配“foobar”。不是我要找的。那么,如何使正则表达式仅在存在一个或另一个术语时匹配 谢谢 你可以用一个正则表达式来实现这一点,但为了可读性,我建议你做一些类似于 /((foo)|(bar))/ (/foo/ and

正在寻找一些正则表达式帮助。 我想设计一个表达式,使字符串与“foo”或“bar”匹配,但不能同时与“foo”和“bar”匹配

如果我做了像

/((foo)|(bar))/
(/foo/ and not /bar/) || (/bar/ and not /foo/)
它将匹配“foobar”。不是我要找的。那么,如何使正则表达式仅在存在一个或另一个术语时匹配


谢谢

你可以用一个正则表达式来实现这一点,但为了可读性,我建议你做一些类似于

/((foo)|(bar))/
(/foo/ and not /bar/) || (/bar/ and not /foo/)

我会用这样的东西。它只是检查单词周围的空格,但如果使用
\w
,则可以使用
\b
\b
检查边框。这将与“foo”或“bar”匹配,因此显然您也必须替换空白,以防万一。(假设您正在替换任何东西。)


我不认为用一个正则表达式就可以做到这一点。边界可能有效,也可能无效,这取决于您所匹配的对象

我将分别匹配每个正则表达式,并对结果执行XOR

foo = re.search("foo", str) != None
bar = re.search("bar", str) != None
if foo ^ bar:
    # do someting...

我曾尝试与Regex Coach对抗:

x foo y
x bar y
x foobar y
如果我选中
g
选项,它确实会匹配所有三个单词,因为它会在每次匹配后再次搜索。
如果不希望出现这种行为,可以锚定表达式,例如,仅在单词边界上匹配:

\b(foo|bar)\b
在问题上提供更多的上下文(数据是什么样子的)可能会给出更好的答案

\b(foo)\b|\b(bar)\b

只使用第一个。

你可能想考虑一下?条件测试

(?(?=regex)then|else)

如果您的正则表达式语言支持它,请使用:


使用单词边界,你可以得到单个单词

me@home ~  
$ echo "Where is my bar of soap?" | egrep "\bfoo\b|\bbar\b"  
Where is my bar of soap?  

me@home ~  
$ echo "What the foo happened here?" | egrep "\bfoo\b|\bbar\b"  
What the foo happened here?  

me@home ~  
$ echo "Boy, that sure is foobar\!" | egrep "\bfoo\b|\bbar\b"  

除了“foo”和“bar”之外,您没有指定内容的行为,或者在没有其他内容的情况下重复一个内容。e、 例如,“food”或“barbarian”是否匹配

假设您希望匹配只包含一个“foo”或“bar”实例的字符串,但不同时包含两个实例,也不包含同一个实例的多个实例,而不考虑字符串中的任何其他内容(即,“food”匹配和“barbarian”不匹配),然后,可以使用一个正则表达式,它返回找到的匹配数,并且仅在找到一个匹配时才认为它成功。e、 例如,在Perl中:

@matches = ($value =~ /(foo|bar)/g)  # @matches now hold all foos or bars present
if (scalar @matches == 1) {          # exactly one match found
  ...
}

如果允许对同一目标进行多次重复(即“野蛮人”匹配),则可以通过遍历匹配列表来使用相同的一般方法,以查看匹配是否都是相同文本的重复,或者是否还存在其他选项。

如果您想要真正的异或,我只是在代码中而不是在正则表达式中这样做。在Perl中:

/foo/ xor /bar/
但你的评论是:

匹配:“foo”、“bar”非匹配: “foooo”“barfoo”“foobarfoo”“barbar” “巴福”

表示您并不是真正在寻找独占或。你是说 “难道
/foo | bar/
只匹配一次吗?”

这就是我使用的:

/^(foo|bar){1}$/

请参阅:在“重复”下,这将采用“foo”和“bar”,但不采用“foobar”,也不采用“blafoo”和“blabar”:

/^(foo|bar)$/

^ = mark start of string (or line)
$ = mark end of string (or line)
/\b(foo|bar)\b/

\b = mark word boundry

这将包括'foo'和'bar'以及'foo-bar'和'bar-foo',但不包括'foobar',不包括'blafoo'和'blabar':

/^(foo|bar)$/

^ = mark start of string (or line)
$ = mark end of string (or line)
/\b(foo|bar)\b/

\b = mark word boundry

我知道这是一个迟来的条目,但只是为了帮助其他可能正在寻找的人:

(/b(?:(?:(?!foo)bar)|(?:(?!bar)foo))/b)

foobar是否会匹配,因为它包含“foo”和“foobar”?“foonbar”怎么样?你能提供匹配和非匹配的例子吗?匹配:“foo”,“bar”非匹配:“foofoo”“barfoo”“foobarfoo”“barbar”“barfoo”“barfoo”如果你不想让“foofoo”匹配,那么你就不是在说异或。事实上,我很确定我会把XOR逻辑放在代码本身中,而不是放在regexp中。或者更好,/foo/xor/bar/,如果您的语言具有xor运算符。(Perl有。)@Ralf这不是一个单独的表达式,而是两个用逻辑OR运算符连接的表达式。比公认的答案更优雅的解决方案,特别是当你有两个以上的案例时。你为什么要添加
{1}
,这意味着什么?这是错误的,这只意味着
foo
bar
只能匹配一次。我同意@Karl的说法,这不是异或。它只检查整个字符串是“foo”还是“bar”