【问题标题】:capturing words with optional prefiex使用可选前缀捕获单词
【发布时间】:2017-05-09 09:55:55
【问题描述】:

我需要扩展现有的正则表达式来捕获一些可选前缀。 我当前的正则表达式工作正常:

(?:\b)(?:mon|tue|wed|thu|fri|sat|sun)(?:\b)

并匹配由单词边界分隔的任何这些单词。 例如,给定字符串"mon-sun.sat",它将分别匹配monsunsat

现在,假设上面的单词可以选择以"each" "only" "any" 之类的术语作为前缀,例如"mon. any-tue or only-wed. sat. each weekend"

我想扩展我的正则表达式以匹配和捕获(在上面的示例中),术语monany tueonly wedsat 但显然不是each,因为它没有为列表中的术语添加前缀。在实践中,要捕获的模式是:可选的prefix,后跟day of the week

我曾尝试以多种方式扩展我的正则表达式,但均未成功。我想我搞砸了边界这个词。

换句话说: 有两组词说P={each,only,any}W={mon,tue,wed,thu,fri,sat,sun}。我需要匹配任何元素w in W 可选地以元素p in P 为前缀。分隔符可以是任何 \b。

编辑: 我目前的尝试是 (:?\b) ((any|only|each)?(:?\b)) (:?mon|tue|wed|thu|fri|sat|sun) (:?\b) 但只会匹配montuewedsat

【问题讨论】:

  • 请分享不适合您的最佳尝试。为了解释问题,我们需要知道问题是什么。另外,当说“前缀”时,您的意思是在原始正则表达式中列出的替代项之前应该有一个连字符吗?
  • 有两组词说P={each,only,any}W={mon,tue,wed,thu,fri,sat,sun}。我需要匹配任何元素w in W 可选地以元素p in P 为前缀。分隔符可以是任何\b
  • \b 是一个零宽度断言,它不匹配任何文本。使用\W* 确保两个单词之间的任何非单词字符都匹配。看看regex101.com/r/QOWEKL/1。看看你的尝试,你破坏了非捕获组,你甚至根本不需要,(:?) 匹配可选的:

标签: regex


【解决方案1】:

你可以使用

\b(?:(any|only|each)\W+)?(mon|tue|wed|thu|fri|sat|sun)\b

regex demo

详情

  • \b - 前导词边界
  • (?:(any|only|each)\W+)? - 一个可选的非捕获组,匹配 1 次或 0 次出现:
    • (any|only|each) - 一个完整的单词(前面的单词边界已经用上面的\b 断言,后面的单词边界用\W+ 保证)any, only each`
    • \W+ - 1 个或多个非单词字符。
  • (mon|tue|wed|thu|fri|sat|sun)\b - 一个完整的单词(由于初始的\b\W+ 和捕获组之后的\b):montuewedthufrisatsun

请注意,(?:...)? 非捕获组用于包装可选子模式,因为与捕获组相比,它不会为捕获创建任何内存缓冲区。 ? 是使其匹配组内子模式序列的 1 次或 0 次出现的量词。 \W 是一个非单词 char 速记字符类,它使用任何非单词 char(因此,任何标点符号和符号,甚至空格都会匹配)。

【讨论】:

  • 对不起,我在(mon 之前漏掉了边界这个词,我有它(至少在 V1 中),但它以某种方式被删除了。我们肯定需要它,因为之前的组是可选的,我们需要确保一周中的日期前面有一个单词边界。我把那个词边界加回来了。
  • 在开头只放一个:\b(?:(any|...)\W+)?(mon...
  • 现在,它看起来应该如此。
  • 谢谢,看起来不错。为什么我的初始和最终(?:\b) 更改为\b
  • @giog:是的,(?:\b) 等于 \b\W_ 不匹配,如果需要匹配,可以,将其添加到字符类 [\W_]
猜你喜欢
  • 2012-07-25
  • 1970-01-01
  • 2020-07-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-18
  • 2013-04-17
  • 1970-01-01
相关资源
最近更新 更多