Javascript中正则表达式的递归匹配

IT技术 javascript regex
2021-01-12 10:49:59

示例字符串: $${a},{s$${d}$$}$$

我想先匹配$${d}$$并替换一些文本,这样字符串就会变成$${a},{sd}$$,然后$${a},{sd}$$将被匹配。

6个回答

令人讨厌的是,Javascript 没有提供 PCRE 递归参数(?R),因此处理嵌套问题远非易事。然而这是可以做到的。

我不会复制代码,但如果您查看Steve Levithan 的博客,他会提供一些关于该主题的好文章。他应该这样做,他可能是 JS 中 RegExp 的主要权威。他编写了XRegExp,它替换了大部分缺失的 PCRE 位,甚至还有一个匹配递归插件!

我不会说 XRegExp 替换了“大部分缺失的部分”,但它确实有帮助。但是,对于真正的正则表达式,您需要完整的属性和字素支持。现在超过 80% 的网络都是 Unicode,在浏览器中无法应付它是一种犯罪。
2021-03-12 10:49:59
@Orbling:不,只有 UTF-8,不是 UTF-16。没有人用 UTF-16 做网页:这很愚蠢。UTF-16 具有 UTF-8 和 UTF-32 的所有缺点,但没有任何优点。UTF-16 是一个遗憾的inheritance。
2021-03-17 10:49:59
@tchrist:UTF8/16 越来越多地作为标准输出,因为网络服务器和编辑器正在采用它作为默认值。无论如何,curl引号是可怕的东西,是程序员的诅咒。;-)
2021-03-20 10:49:59
@Orbling 说英语的人确实使用 Unicode,而且很多‼请看这篇对大型英语语料库的分析从那以后我就做了其他的。大多数网页都是 Unicode 格式的——你只是没有意识到这一点。没有它,你就不能正确地写英语:没有curl引号,没有 10 英镑的钞票,没有 5 美分的纸币,&c&c。在过去的 5 年中,Web 上的Unicode增长800%那是快速的变化,而不是缓慢的变化‼人们没有注意,但 Unicode 还是来了。
2021-03-25 10:49:59
@tchrist:英语世界几乎不使用它,因此对于可以改变它的人来说,它并不重要。再加上在网络的基础级别上不可能缓慢变化的原则,这使得这些事情仍然遥不可及。至少可以说不方便。
2021-03-27 10:49:59

我自己写的:

String.prototype.replacerec = function (pattern, what) {
    var newstr = this.replace(pattern, what);
    if (newstr == this)
        return newstr;
    return newstr.replace(pattern, what);
};

用法:

"My text".replacerec(/pattern/g,"what");

PS:正如@lededje 所建议的,在生产中使用此函数时,最好有一个限制计数器以避免堆栈溢出。

这不能无限递归……没有递归吗?
2021-03-20 10:49:59
我在运行了一年多的生产代码中使用了它。正则表达式无限次地继续匹配是一种罕见的机会。所以没有溢出!这是直接从 JavaScript 代码进行递归替换的快速方法。
2021-03-22 10:49:59
堆栈的限制不是无穷大。IE6 只能处理 1130 次调用。这不是 1130 次正则表达式匹配,而是全部正则表达式匹配加上您正在进行的其他任何操作。说这是一个足够好的答案是不正确的,因为有人可能在已经是功能密集型的环境中使用它,并且不应该添加到堆栈中的东西可能会使其溢出。所以-1。
2021-03-22 10:49:59
我相信第 5 行 {return newstr.replace(pattern, what);} 应该是 {return newstr.replacerec(pattern, what);} 以获得递归。(在“替换”的末尾添加“rec”)。同意?
2021-03-25 10:49:59

由于您想递归地执行此操作,因此最好使用循环进行多次匹配。

正则表达式本身并不适合递归任何东西。

PCRE 正则表达式非常适合递归模式,不幸的是 Javascript 没有这种能力。
2021-04-06 10:49:59

您可以尝试\$\${([^\$]*)}\$\$[^\$]如果捕获的组包含,则平均值不捕获$

var re = new RegExp(/\$\${([^\$]*)}\$\$/, 'g'),
  original = '$${a},{s$${d}$$}$$',
  result = original.replace(re, "$1");
  
console.log('original: ' + original)
console.log('result: ' + result);

var content = "your string content";
var found = true;
while (found) {
    found = false;
    content = content.replace(/regex/, () => { found = true; return "new value"; });
}
你错了。如果没有更多匹配的值 'found' 保持 false 并且 while 循环退出。“新值”是匹配字符串的新值。
2021-03-21 10:49:59
尽管这些概念可能存在,但有太多不起作用、可能会出错,并且没有解决所提出的问题。
2021-03-22 10:49:59
它没有回退,所以如果它不匹配,它可能会超过内存限额。还有什么是“新value”,它应该从哪里来?而且您没有展示 OP 的正则表达式如何在此代码中实际工作。
2021-03-23 10:49:59
会出什么问题?这个简单的模式可以用正确的正则表达式定义解决问题中的问题。
2021-04-09 10:49:59