【问题标题】:Regex to match opening parentheses not preceded by "]"正则表达式匹配前面没有“]”的左括号
【发布时间】:2015-04-29 08:21:10
【问题描述】:

我有一些文本,其中普通降价和自定义降价扩展混合在一起。这很好用。

[My Link Title](http://example.com)

(extension: value attribute: value)

但是,我有一个问题:要在编辑文本时应用一些样式,我需要一种方法来匹配扩展 sn-p 的左括号,而不匹配 markdown 链接的左括号。

换句话说:我需要一个正则表达式(适用于 javascript)来匹配左括号(并且只有括号)

  1. [a-z0-9]+:
  2. 进行
  3. 前面没有] 字符。

我当前的正则表达式(它可以很好地匹配扩展标签左括号,但不幸的是也包括降价链接左括号)如下所示:/\((?=[a-z0-9]+:)/i

我看到人们在正则表达式的开头使用带有否定的肯定前瞻,例如 /(?=[^\]])\((?=[a-z0-9]+:)/i 来检查 PHP 中的。不幸的是,这似乎不适用于 javascript。


更新

感谢您的提示!

我遇到的问题是我正在为 CodeMirror 创建一个 “简单模式” 语法模式以应用突出显示。这允许您指定将应用于匹配字符但不允许对匹配进行任何进一步操作的正则表达式和标记。但是,您可以编写一个完整的语法模式,您可以在其中执行此类操作,但我无法做到这一点:-s

毕竟,我选择了另一种解决方案。我刚刚创建了两个正则表达式:

  1. 将所有左扩展括号与除“]”之外的前一个字符匹配:
    /[^\]]\((?=[a-z0-9]+:)/i
  2. 匹配所有不带任何前置字符的左扩展括号:
    /^\((?=[a-z0-9]+:)/i

尽管它不是最干净的方式,但它现在似乎工作得很好。

【问题讨论】:

  • 您要求的是在 JS 中不可用的负面后视。此外,当您需要前瞻和后视(如字符串反转)时,没有已知的解决方法。您将不得不匹配的不仅仅是一个括号并使用捕获组。类似/(^|[^\])\((?=[a-z0-9]+)/i.
  • @stribizhev - 这通常是正确的,但在这种情况下,您可能可以反转字符串并使用\b\((?!\]),这非常简单。
  • @Kobi:没错,唯一的] 是一个非单词字符。伟大的!因此,如果前瞻和后视的宽度可变,则没有解决方案。
  • @Kobi 感谢您的提示!请查看我现在使用的解决方案的更新问题。

标签: javascript regex


【解决方案1】:

使用skip and match trick

\[[^\]]+\]\([^\)]+\)|(\(\b)
  • \[[^\]]+\]\([^\)]+\) - 匹配 []() 链接(如果这太混乱,你也可以写 \[.*?\]\(.*?\)),或者 -
  • (\(\b) - 匹配并捕获直接位于字母数字字符之前的开括号。

工作示例:https://regex101.com/r/tY9sS4/1

您必须查看结果并仅处理捕获到 $1 分组的匹配项,而忽略其他匹配项。

【讨论】:

  • 不错的解决方案!我遇到的唯一问题是我正在为 CodeMirror 创建一个“简单模式”语法模式以进行突出显示。这允许您指定将应用于匹配字符的正则表达式和令牌,并且不允许对匹配项进行任何进一步的操作。但是,您可以编写一个完整的语法模式,您可以在其中执行此类操作,但我无法做到这一点:-s
  • @DieserJonas - 哦,真可惜!您确实说过“匹配一个左括号(并且只有括号)”。您可能很难使用 JavaScript 正则表达式引擎,它很弱...谢谢!
  • @DieserJonas - 另外,我不知道 CodeMirror,但是在寻找 ( 之前,你能在一个语法规则中匹配 [...](...) 吗?通常这些工具都有优先级。
  • 我刚刚使用我现在使用的解决方案编辑了我的原始问题。问题是这种“简单模式”基本上是一个状态机,它在状态之间切换并基于正则表达式应用令牌类型。这有点有限。
  • 如果我能够编写完整的语法模式,我想我可以很好地使用您的解决方案。不幸的是,这比我目前的技能水平高一点。我可能会在未来某个时候重新审视这个问题,并根据您的回答做出更好的解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多