由于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
属性的内容吗?
答案 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中删除,因此它可以用于我的目的。