使用正则表达式使用字符串替换在JavaScript中引用嵌套组

时间:2011-05-05 20:08:40

标签: javascript regex replace regex-group

由于jQuery处理脚本标记的方式,我发现有必要使用正则表达式进行一些HTML操作(是的,我知道......不是理想的工具)。不幸的是,似乎我对JavaScript中捕获的组如何工作的理解是有缺陷的,因为当我尝试这个时:

var scriptTagFormat = /<script .*?(src="(.*?)")?.*?>(.*?)<\/script>/ig;

html = html.replace(
    scriptTagFormat, 
    '<span class="script-placeholder" style="display:none;" title="$2">$3</span>');

脚本标记被替换为跨度,但生成的title属性为空。 $2不应该匹配脚本代码的src属性的内容吗?

5 个答案:

答案 0 :(得分:4)

群组的嵌套是无关紧要的;它们的编号严格取决于正则表达式中它们的开括号的位置。在您的情况下,这意味着它的组#1捕获整个src="value"序列,而组#2只捕获value部分。

答案 1 :(得分:1)

.*?匹配太多,因为以下群组是可选的,==&gt;您的src.*?周围的?匹配。如果您在第一组之后删除了.*?,那就可以了。

更新:正如@morja指出你的解决方案是将第一个/<script (?:.*?(src="(.*?)"))?.*?>(.*?)<\/script>/ig移动到可选的src部分。

为了完整性:(?:)

你可以看到它here on rubular(也纠正了我的链接)

如果您不想使用第一个捕获组的内容,请使用/<script (?:.*?(?:src="(.*?)"))?.*?>(.*?)<\/script>/ig

将其设为非捕获组
{{1}}

然后你想要的结果是1美元和2美元。

答案 2 :(得分:1)

试试这个:

/<script (?:(?!src).)*(?:src="(.*?)")?.*?>(.*?)<\/script>/ig

见这里:rubular

正如stema所写,.*?匹配得太多了。使用否定预测(?:(?!src).)*,您只会匹配src属性。

但实际上在这种情况下你也可以将.*?移动到可选部分:

/<script (?:.*?src="(.*?)")?.*?>(.*?)<\/script>/ig

见这里:rubular

答案 3 :(得分:0)

你能发布你正在检索的html吗?您的代码在一个简单示例中正常工作:jsfiddle (warning: alert box)

我的第一个猜测是你的一个脚本标签没有src意味着你留下了一个捕获组(脚本内容)。

答案 4 :(得分:0)

我认为正则表达式本身并不能完全符合我的要求,所以这是我修改以解决问题:

var scriptTagFormat = /<script\s+((.*?)="(.*?)")*\s*>(.*?)<\/script>/ig;

html = html.replace(
    scriptTagFormat, 
    '<span class="script-placeholder" style="display:none;" $1>$4</span>');

之前,我想避免在替换span上设置非标准属性。此代码盲目地复制所有属性。幸运的是,当我插入HTML时,非标准属性不会从DOM中删除,因此它可以用于我的目的。