如何使用JavaScript正则表达式删除字符串的一部分,而不重复分隔字符串。

4

我想在两个已知的子字符串(<foo>和</foo>)之间删除一个未知的子字符串。例如,我希望将以下内容转换为:

hello <foo>remove me</foo>

to:

hello <foo></foo>

我可以用以下方式实现:

s = ...
s.replace(/<foo>.*?<\/foo>/, '<foo></foo>')

但我想知道是否有一种方法可以在正则表达式和替换文本中不重复使用已知的子字符串(<foo></foo>)来完成这个操作。

2个回答

10

你可以在一个匹配组中捕获标签,并且稍后将其作为反向引用使用:

var repl = s.replace(/<(foo)>.*?<\/\1>/, '<$1></$1>');
//=> hello <foo></foo>

注意,\1$1是对捕获组#1的反向引用。

图片描述


2
你们太棒了。谢谢! - Ellen Spertus
只是问一下,对于 <foo><a>...</a></foo> 这种格式,它能正常工作吗? - Braj
1
干净高效,加一分 :) - zx81

2

尝试使用分组的正则表达式。

(?:<foo>)(.*?<\/foo>)

regex101在线演示

图片表示:Debuggex演示

输入图像描述

示例代码:

var re = /(?:<foo>)(.*?<\/foo>)/;
var str = 'hello <foo>remove me</foo>';
var subst = '<foo></foo>';

var result = str.replace(re, subst);

输出:

hello <foo></foo>

非常感谢!我希望我能够接受两个答案。 - Ellen Spertus
1
@Braj:你的模式唯一的问题是,当字符串为"<foo>abcdefg</foo><foo>hijklmno</foo>"时,它将匹配整个字符串而不是<foo>abcdefg</foo>,因为量词*是贪婪的。关于regex101步骤(或regexbuddy步骤):查看需要多少步骤才能使您的模式成功或失败是有用的。但请记住,这些信息并不总是与实际的模式性能相关。确定的方法是使用计时器。 - Casimir et Hippolyte
1
@Braj:是的,如果你将量词设为懒惰模式,它会起作用。但对于长字符串来说,懒惰模式比贪婪模式要慢。 - Casimir et Hippolyte
@CasimiretHippolyte,感谢你的建议。我非常感激。 - Braj
2
@Braj:没问题,正则表达式并不容易。需要掌握很多概念,包括字符类、贪婪/懒惰、回溯、原子/占有、环视、捕获/反向引用/子模式/命名模式、递归、回溯控制动词等等。 - Casimir et Hippolyte
显示剩余21条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接