只匹配前缀或后缀的正则表达式匹配(异或)

5
我有一个模式,我将其称为Z(实际模式有点长,但对问题不重要)。简单来说,我想能够匹配\*\sZZ\:,但不能两者都匹配,也不能两者都不匹配。
我尝试使用预查(类似于下面的代码),但由于前缀和后缀之间的模式,它们无法起作用。
(\*\s(?!\:))Z((?<!\*)\:)

有没有一种方法可以在不重复模式的情况下完成这个操作(例如(\*\sZ|Z\:))?
关于我的模式,简短说明一下,Z 模式中没有 \*,只有前缀中有。相反,在 Z 模式中也没有 \:,如果在任何其他字符后面,则只在后缀中出现,但是在 Z 后面立即跟随时才有(后缀之后有一个 .* 捕获)。

你使用的是哪种编程语言? - ndnenkov
1
虽然我一直使用在线 pcre 测试器简化操作,但是我会用 Java。 - Rogue
1
我认为在Java中只使用正则表达式无法完成这个任务。提取“Z”到一个单独的字符串中,并使用它来创建整体模式,这样就不必重复它。 - ndnenkov
尝试使用正则表达式 ((?:^|\b)pre)\S+|\S+?suf(?:\b|$),其中 pre 代表前缀,suf 代表后缀。它将捕获所有具有给定前缀或后缀的单词。 - Saleem
这个怎么样?https://regex101.com/r/rE3lP8/1? - fronthem
1个回答

5
有没有一种不需要复制模式就能完成这个任务的方法?
答案是“没有”。与正则表达式的基本属性andor不同。在正则表达式中,您可以通过使用连接构建and表达式,并分别使用|构建or表达式。
但无论如何,如果您仍然想完成您的工作,我建议您这样做。
首先,您已经有了两个模式。
\*\sZ

并且

Z\:

所以,正如你所说的那样,这两种模式不能同时发生。

因此根据xor的属性:

A xor B = (A & ~B)|(~A & B)。

最终我们可以得到:

\*\sZ(?!\:)|(?<!\*\s)Z\:

查看演示


尽管 OP 说了其中之一,他只是指简单的 |。他只是想知道如何避免重复使用 Z - ndnenkov
他问道:“是否有一种方法可以在不重复模式的情况下完成这个任务?”答案是“否”,因为 XOR 不是正则表达式的基本构建块。 - fronthem
我已经回答了“NO”,并建议他完成他所说的“我想能够匹配\*\sZZ\:,但不能同时匹配也不能都不匹配”的方法。我在我的答案中为他提供了一个正则表达式。 - fronthem
1
目前已被接受,我相当确定这是情况,但希望在正则表达式中有一些神奇的东西我不知道。我只是将模式保存在变量中并进行连接。 - Rogue

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接