正则表达式在引号中捕获一个词或两个词

Regex Capture one word OR two words in quotes

我正在尝试在我的搜索中实施 gmail 样式过滤器,但我遇到了这个正则表达式问题。我需要在引号中捕获一个词或两个词(但没有引号本身)这是 PCRE (PHP)

name:mark

期望的结果:第一个捕获组应该是标记

name:"mark"

期望的结果:第一个捕获组应该是标记

name:"mark wilson"

期望的结果:第一个捕获组应该是 mark,第二个捕获组应该是 wilson

name:mark wilson

期望的结果:第一个捕获组应该是 mark,wilson 被忽略

我得到的最接近的是 name:(\w+|\"\w+(?>\"|\s([a-z.'-]+\"))) 它完美地捕捉了示例 1,但是示例 2 仍然包含引号,示例 3 最终为:

第 1 组:"mark wilson"(包括引号)

第 2 组:wilson"(包括引用)

我已经尝试过前瞻和后视,但我都没有取得任何进展

如有任何帮助,我们将不胜感激。蒂亚

1 选项可以使用 if/else clause,它将在第 2 组中给出标记,在第 3 组中给出 wilson。第一组将捕获 ",它可用于 if else 检查组 1 的存在。

\w+:(")?(\w+(?:\h+(\w+))?)(?(1)")

Regex demo

如果名字后面的 space 不应该存在,您也可以将其分组并将值放在第 3 组和第 4 组中

\w+:(")?((\w+)(?:\h+(\w+))?)(?(1)")

Regex demo

您还可以获取或不获取引号之间的单个值,或者使用 branch reset group

捕获捕获组中的名字或第二个名称
\w+:(?|"(\w+)(?:\h+(\w+))?"|(\w+))

说明

  • \w+: 匹配 1+ 个单词字符
  • (?|分支重置组
    • "(\w+) 捕获组 1,匹配 1+ 个单词字符
    • (?:非捕获组
      • \h+ 匹配 1+ 水平白色space 字符
      • (\w+) 捕获组 2,匹配 1+ 个单词字符
    • )?关闭群组并设为可选
    • " 匹配 "
    • |
    • (\w+) 捕获组 1,匹配 1+ 个单词字符
  • )关闭分支重置组

Regex demo

重点是您不能对任意数量的组执行此操作,您必须在设计时在模式中指定它们。

您可以将这样的模式与 branch reset group:

\w+:(?|(\w+)|"(\w+)(?:\h+(\w+))?(?:\h+(\w+))?")

regex demo。在末尾添加更多 (?:\h+(\w+))? 模式以支持最多 N 个可选词。

详情

  • \w+: - 1+ 个单词字符,然后是 :
  • (?|(\w+)|"(\w+)(?:\h+(\w+))?(?:\h+(\w+))?") - 分支重置组,其中组共享相同的 ID:
    • (\w+) - 第 1 组:一个或多个单词字符
    • | - 或
    • "(\w+)(?:\h+(\w+))?(?:\h+(\w+))?" -
      • " - 一个 " 字符
      • (\w+) - 第 1 组:一个或多个单词字符
      • (?:\h+(\w+))? - 序列的可选出现:
      • \h+ - 1 个或多个水平空格
      • (\w+) - 第 2 组:一个或多个单词字符
      • (?:\h+(\w+))?" - 同上,但第 3 组等