这里有一些简单的复制粘贴代码,不仅适用于精确字词异常。
复制/粘贴代码:
在以下正则表达式中,仅用您的正则表达式替换全大写部分。
Python 正则表达式
pattern = r"REGEX_BEFORE(?>(?P<exceptions_group_1>EXCEPTION_PATTERN)|YOUR_NORMAL_PATTERN)(?(exceptions_group_1)always(?<=fail)|)REGEX_AFTER"
红宝石正则表达式
pattern = /REGEX_BEFORE(?>(?<exceptions_group_1>EXCEPTION_PATTERN)|YOUR_NORMAL_PATTERN)(?(<exceptions_group_1>)always(?<=fail)|)REGEX_AFTER/
PCRE正则表达式
REGEX_BEFORE(?>(?<exceptions_group_1>EXCEPTION_PATTERN)|YOUR_NORMAL_PATTERN)(?(exceptions_group_1)always(?<=fail)|)REGEX_AFTER
JavaScript
在 2020 年 6 月 17 日之前不可能,并且在不久的将来可能不会。
完整示例
REGEX_BEFORE = \b
YOUR_NORMAL_PATTERN = \w+
REGEX_AFTER =
EXCEPTION_PATTERN = (苹果|橙子|果汁)
Python 正则表达式
pattern = r"\b(?>(?P<exceptions_group_1>(apple|orange|juice))|\w+)(?(exceptions_group_1)always(?<=fail)|)"
红宝石正则表达式
pattern = /\b(?>(?<exceptions_group_1>(apple|orange|juice))|\w+)(?(<exceptions_group_1>)always(?<=fail)|)/
PCRE正则表达式
\b(?>(?<exceptions_group_1>(apple|orange|juice))|\w+)(?(exceptions_group_1)always(?<=fail)|)
它是如何工作的?
这使用了相当复杂的正则表达式,即原子组、条件、Lookbehinds 和命名组。
(?> 是原子组的开始,这意味着它不允许回溯:这意味着,如果该组匹配一次,但后来由于后向失败而失效,那么整个组将不匹配。 (在这种情况下,我们想要这种行为)。
(?<exceptions_group_1> 创建一个命名的捕获组。它比使用数字更容易。请注意,该模式首先尝试查找异常,如果找不到异常,则返回到正常模式。
请注意,原子模式首先尝试查找异常,如果找不到异常,则返回到正常模式。
真正的魔力在于(?(exceptions_group_1)。这是一个询问 exceptions_group_1 是否成功匹配的条件。如果是,那么它会尝试查找always(?<=fail)。这种模式(正如它所说的那样)总是会失败,因为它会寻找“always”这个词,然后它会检查“does "ways"=="fail"',但它永远不会。
-
因为条件失败,这意味着原子组失败,并且因为它是原子的,这意味着它不允许回溯(试图寻找正常模式),因为它已经匹配了异常。
这绝对不是这些工具的预期用途,但它应该可靠且高效地工作。
Ruby 中原始问题的准确答案
/\b(?>(?<exceptions_group_1>(apple|orange|juice))|\w+)(?(<exceptions_group_1>)always(?<=fail)|)/
与其他方法不同,此方法可以修改为拒绝任何模式,例如任何不包含子字符串“apple”、“orange”或“juice”的单词。
/\b(?>(?<exceptions_group_1>\w*(apple|orange|juice))|\w+)(?(<exceptions_group_1>)always(?<=fail)|)/