努力使用正则表达式来匹配内部引号+括号。我需要 negative/positive look-ahead/behind 吗?

Struggling with a regex for matching inner quote+parenthesis. Do I need negative/positive look-ahead/behind?

我正在尝试对以下字符串执行正则表达式:

  1. "sonoma wildfires"
  2. sonoma and (wild* or stratus or kincade)
  3. sonoma and (wild or "stratus kincade")

... 这样我就能得到以下匹配项:

  1. ['"sonoma wildfires"']
  2. ['sonoma', 'and', '(wild* or stratus or kincade)']
  3. ['sonoma', 'and', '(wild* or "stratus or kincade")']

我正在使用以下正则表达式:

/\w+\*?|["(][^()"]+[")]/g

前两个字符串正确匹配。

但是对于第三个字符串,我得到了这个匹配项:

['sonoma', 'and', '(wild* or "', 'stratus', 'kincade']

...而我想要的是:

['sonoma', 'and', '(wild* or "stratus or kincade")']

它匹配第一个内括号,但也抓住了第一个内引号。我一直在用消极和积极的前瞻来调整正则表达式,但我很难弄明白。

/\w+\*?|["(](?<!\()[^()"]+(?!\))[")]/g

如果这 3 个案例是您寻找的唯一刻板印象,您可以试试这个

/(\w+) +(and) +(\(.+\))|(\".+\")/g

它将寻找

  • word and (expression)
  • "表达式"

在正则表达式中测试它: https://regexr.com/5adgh

[编辑]

抱歉我忘记了捕获组

您尝试的第一个模式 \w+\*?|["(][^()"]+[")] 没有给出所需的匹配,因为交替的第二部分首先匹配任何列出的字符 ["(] 并且它可以匹配 (

然后下一部分 [^()"]+ 匹配除了列出的任何字符的一次或多次出现。匹配不会到达右括号,因为它不能穿过第三个示例中出现在否定字符 class.

中的双引号

您不需要任何环顾四周,您可以添加第三个备选方案。

\w+\*?|\([^()]+\)|"[^"]+"

说明

  • \w+\*? 匹配 1+ 个单词字符和可选 *
  • |
  • \([^()]+\) 使用 negated character class
  • 从左括号到右括号进行匹配
  • |
  • "[^"]+" 使用否定字符从双引号到双引号匹配 class

Regex demo

[
  `sonoma wildfires"`,
  `sonoma and (wild* or stratus or kincade)`,
  `sonoma and (wild or "stratus kincade")`,
].forEach(s => console.log(s.match(/\w+\*?|\([^()]+\)|"[^"]+"/g)));