regex 正则表达式与多个线索:查找所有最短的选项

wn9m85ua  于 2023-08-08  发布在  其他
关注(0)|答案(2)|浏览(113)

我有一个与这个问题密切相关的问题:Regex find match within a string
在这种情况下,问题是找到Warner Music Group而不是XYZ becomes Chief Digital Officer and EVP, Business Development of Warner Music Group

Ole Abraham  of XYZ becomes Chief Digital Officer and EVP, Business Development of Warner Music Group.

字符串
使用.*\bof\s+([^.]+)求解
现在我遇到了一个非常类似的问题,不同的是我想要所有的匹配,而以前的解决方案只返回一个。下面是我使用上述解决方案的基本设置:https://regex101.com/r/bIbFaW/1
问题是对于字符串

This is a test with a string with punctuation, and an end. Then test words, and more text. And here whith more text with more punctuation, like that.


模式.*\bwith(.*?),只会得到more punctuation(一个很好的匹配),缺少第一个句子中较早的选项punctuation
是否有可能做到这一点,或者我应该采取不同的方法?例如,with(.*?),获取所有匹配项,但它们是较长的选项(a string with punctuation而不是punctuation,)。然后,我可以尝试在我的匹配中找到匹配,但此时这样做会产生不相关的开销,如果可能的话,最好避免这种开销。


的数据

fcwjkofz

fcwjkofz1#

您可以避免将逗号与取反字符类[^,]匹配,并在匹配with后匹配除逗号以外的任何字符,或者使用tempered greedy token再次匹配。
然后匹配结尾处的逗号。

\bwith\b((?:(?!\bwith\b)[^,])*),

字符串

  • \bwith\b匹配单词with
  • (捕获组1
  • (?:非捕获组作为整体部分重复
  • (?!\bwith\b)[^,]如果当前位置后面没有直接跟单词“with”,则匹配除逗号以外的任何字符
  • )*关闭非捕获组,并选择重复该操作
  • )关闭组1
  • ,匹配逗号

Regex demo

hgb9j2n6

hgb9j2n62#

如果你的句子以一个点结束怎么办?还是另一个标点符号

为了使它更简单,更容易阅读,而不使用regex lookaheads,这使得它运行更多的步骤,我建议这个启动:

\bwith\s+([^,.]*)/g

字符串
V1:https://regex101.com/r/kUXu9z/1

  • \b匹配单词边界,以避免匹配“bandwith”中的“with”或类似内容。
  • with匹配单词“with”。
  • \s+,因为我们知道它们至少应该是一个空格字符,包括可能的换行或其他字符。
  • ([^,.]*)([^,.]+)是匹配任何非逗号或点的字符的捕获组。但这份名单可能还不够,因为你可以有“!“、“?"、“:“等

如果我们加上一些常用的标点符号:https://regex101.com/r/kUXu9z/2
使用Unicode类字符(在PHP和JavaScript中可用,但对于Python,您可能需要搜索它是否在lib中可用),我们可以使用字符\p{P}\p{Punctuation}punctuation 类,并将其与\P{P}+反转,以便匹配所有不是标点字符的字符:

/\bwith\s+(\P{P}+)/gu


V3:https://regex101.com/r/kUXu9z/3

编辑(因为我没有看到多个“with”的问题)

对不起,我没有清楚地阅读/理解第一次出现的“with”后面跟着逗号前面的第二个“with”的问题。
在这种情况下,我们实际上需要使用负向前查找来避免匹配包含“with”的字符串:

/\bwith\s+(?!\P{P}*\bwith\b)(\P{P}+)/gu


我在空格字符后添加了(?!\P{P}*\bwith\b),以检查我们没有一些非标点符号字符后跟单词“with”。
V4:https://regex101.com/r/kUXu9z/4

相关问题