正则表达式解析带有转义字符的简单markdown而不会产生后顾之忧

时间:2019-01-20 10:48:58

标签: javascript regex typescript

  

注意:这必须在JavaScript RegExp中起作用

我必须这样解析字符串:

yo (p:abc-123-def) meets  \(p:2) \(in the cinema\) \\ (p:3) (p:4\) won't 

我需要提取的全部是(<entity>:<id>)标记,但忽略诸如\(in the ciname\)\\之类的转义字符。在上面的示例中,正则表达式只能匹配

(p:abc-123-def)
(p:3)

\(p:2)\(p:4)除外,因为括号已转义。

现在,我仍然可以修改该标记,因此,如果有一种更简单的方法来完成全部操作,我可以提出建议。如果没有,我就需要能够从正则表达式中获得这些(<entity>:<id>)标记。

类似这样的东西

(?<!\\)\([^(?<!\\)\(]*\)

可以工作,但并非所有浏览器都支持向后搜索组。

3 个答案:

答案 0 :(得分:0)

此正则表达式需要工作

/(?<!\\)\([a-zA-Z]+\:[0-9a-zA-Z_]+\)/g

编辑:此代码是用javascript编译的。

Regexpr Fiddle

答案 1 :(得分:0)

一种方法可能是匹配不需要的内容,并在捕获组中捕获想要保留的内容。

例如:

\\+\([^)]+\)|\([^)]+\\+\)|(\([^:]+:[^:]+\))

Regex demo

  • \\+\([^)]+\)匹配1次以上的反斜杠,然后再打开(直到)
  • |
  • \([^)]+\\+\)匹配(直到1+次反斜杠和)
  • |
  • (捕获组
    • \([^:]+:[^:]+\)匹配(,而不是:,然后匹配:,再匹配:,然后匹配)
  • )关闭捕获组

const regex = /\\+\([^)]+\)|\([^)]+\\+\)|(\([^:]+:[^:]+\))/g;
const str = `yo (p:abc-123-def) meets  \\(p:2) \\(in the cinema\\) \\\\ (p:3) (p:4\\) won't`;
let m;

while ((m = regex.exec(str)) !== null) {
  if (typeof(m[1]) != 'undefined') {
    console.log(m[1]);
  }
}

答案 2 :(得分:0)

反斜杠多次重复会变得很复杂,例如:\\\\\\\\\\\\\\(p:1)。您需要知道反斜杠的数量是偶数还是奇数,才能知道(是否被转义。

第二,括号内出现的冒号也可能被逸出,然后不计数(?)。

因此,我建议使用(?:\\.|[^:)\\])*之类的东西来处理转义字符(.),并对未转义的字符提出一些要求,例如[^:)\\]

这就是结果:

(?:[^\\]|^)((?:\\.)*\((?:\\.|[^:)\\])*:(?:\\.|[^:)\\])*\))

这使用了最新浏览器支持的向后浏览。

如果不能选择向后看,则捕获潜在的反斜杠之前的字符,并为所需部分建立捕获组:

https://www.joshmorony.com/augmented-reality-in-an-ionic-angular-pwa/

所以在这里,您需要处理第一个捕获的组。