将正则表达式从 php 转换为 javascript(回溯断言)



我有这个正则表达式来替换嵌入的 RGB 颜色 {rrggbb}(总是正好 6 个字符括在大括号中)到 html span 标签中:{([a-fA-F0-9]+)}((?>[^{]*{?(?!(?1)}))*)

它是这样使用的:

preg_replace('~{([a-fA-F0-9]+)}((?>[^{]*{?(?!(?1)}))*)~', '<span style="color: #$1">$2</span>', $text);

它在 php 中与preg_replace配合得很好,但是当尝试在 javascript 中使用它时,我遇到了语法错误(?前面的令牌不可量化)

如何让它在javascript中工作?

请注意,我还有另一个正则表达式:{([a-fA-F0-9]{6})}([^{]+)它有效,但是如果我做这样的事情:{ff0000}red text {some text that isn't a color} {00ff00}blue text我得到的输出是:<span style="color: #ff0000">red text </span>{some text that isn't a color} <span style="color: #00ff00">blue text</span>,请注意,{some text that isn't a color}没有包装在任何span标签中,而它仍然应该在上一个标签中。我不知道如何解决它。

JS 正则表达式不支持子例程,但您可以将块定义为变量,并动态构建模式。此外,(?>[^{]*{?(?!(?1)}))*部分过于神秘(并且包含 JS RegExp 也不支持的原子组(?>...)),它所做的只是匹配除{之外的任何 0+ 字符,该字符后面没有十六进制字符直到结束}依此类推直到 RGB 模式(一种展开循环原理变体)。

JS等效项是

var s = "{ff0000}red text {some text that isn't a color} {00ff00}blue text";
var xdigit = "[a-fA-F0-9]+";
var result = s.replace(new RegExp("{("+xdigit+")}([^{]*(?:{(?!"+xdigit+"})[^{]*)*)", "g"), '<span style="color: #$1">$2</span>');
console.log(result);

使用的模式是

/{([a-fA-F0-9]+)}([^{]*(?:{(?![a-fA-F0-9]+})[^{]*)*)/g

在此处查看 JS 正则表达式演示。

  • {-{
  • ([a-fA-F0-9]+)- 第 1 组:一个或多个(使用{6}仅匹配 6 个)十六进制字符
  • }-}
  • ([^{]*(?:{(?![a-fA-F0-9]+})[^{]*)*)- 第 2 组:
    • [^{]*- 除{以外的任何 0+ 字符
    • (?:{(?![a-fA-F0-9]+})[^{]*)*- 以下模式序列的零次或多次出现:
      • {- 一个{,即....
      • (?![a-fA-F0-9]+})- 不跟着 1+ 十六进制字符,然后是}
      • [^{]*- 除{以外的任何 0+ 字符

最新更新