仅替换捕获组 - 正则表达式

时间:2014-06-25 14:09:42

标签: javascript regex

我必须将strong标记替换为b标记。为此,我创建了一个正则表达式/<\s*\/?\s*(strong)\s*>/gi。我只想替换捕获组(strong)。但它取代了整个标签 例如:

"My name is <strong>Tariq</strong>".replace(/<\s*\/?\s*(strong)\s*>/gi,'b');

但结果却是如此 My name is bTariqb.
这里有什么问题......?

3 个答案:

答案 0 :(得分:2)

更新
最后补充:虽然下面的表达式在大多数情况下都有效,但他们不能像这样处理标记:

var example = "I want to <strong>replace</strong> all strong tags with the <i class='strong-text stronger'>better</i> b tag";

标签将被替换为正常,但请注意类属性:strong-text stronger将替换为&#34; b-text ber&#34; 。就stronger而言:添加字边界将解决该问题,但strong-text仍会导致问题。
我们必须确保匹配的子字符串&#34; strong&#34; 不是任何类型的属性。值得庆幸的是,这是一个简单的修复:属性值前面有一个等号,99%的时间是单引号或双引号。然后,使用以下模式阻止我们替换属性值:

example.replace(/(<[^>="']*?)\bstrong\b([^>]*>)/gi, "$1b$2");
//result:
//"I want to <b>replace</b> all strong tags with the <i class='strong-text stronger'>better</i> b tag"

模式说明:
- (<[^>="']*?)与下面相同,但我们排除了='"作为匹配,这意味着<p class="strong">赢了匹配,因为在=<开头之间有strong个字符。 - \bstrong\b:添加了字边界(见下文) - 其余的模式保持不变。

无论如何,这可能和你一样接近,以达到可靠的模式。仍然:如果您计划消耗大量标记,请考虑使用XML解析器,因为RegExp 是该作业的最佳工具


初步回答

你想用&#34; b&#34; 替换&#34; strong&#34; ,并将其他所有内容保留原样,对吧?那么在这种情况下,您应该将之外的所有内容分组,并对替换字符串中的组进行反向引用:

"My name is <strong>Tariq</strong>".replace(/(<\s*\/?\s*)strong(\s*>)/gi,'$1b$2');

与以往一样:RegEx不是使用标记语言的最佳工具,并且您的模式并不完美:例如,它无法处理带有属性的标记。将模式更改为匹配&#34;所有内容 - 除了&#34; 方式,而不是&#34;匹配此或那个&#34;

/(<[^>]*?)strong([^>]*>)/gi

工作原理:

  • (<[^>]*?):匹配并捕获<,然后是任何字符(0或更多),而不是>。非贪婪,匹配将在找到其余模式后立即结束
  • strong:字符串
  • 的字面匹配
  • ([^>]*>):匹配零个或多个非>个字符,以及结束>。此比赛也被捕获

  • 将整个匹配替换为$1b$2<group1>b<group2>,这样可以保留标记中包含的所有属性和/或空格。

结果,正确处理了这样的标记:

"My name is <strong id='someId'>Tariq</strong>".replace(/(<[^>]*?)strong([^>]*>)/gi,'$1b$2');
//output:
//My name is <b id='someId'>Tariq</b>

受到Harpeet(有点缺陷)正则表达式的启发,你也可以选择使用这种模式:

str.replace(/\bstrong\b(?=[^<>]*>)/gi, 'b')

如果不出意外,它看起来更优雅。

说明:

  • \bstrong\b:匹配字符串文字,如果它不是单词的一部分(\b是单词边界)
  • (?=[^<>]*>):仅当后面跟着0个或更多不是<>的字符,以及结束>时。如果我们忽略了排除组中的<,那么当它不属于字符串时,您可能会替换strong一词:'a strong sense<br>'.replace(/strong(?=[^>]*>)/gi, 'b');会导致&#34; ab sense&#34;

答案 1 :(得分:1)

这是一个简短的方法

"My name is <strong>Tariq</strong>.'.replace(/(<\/?)strong(?=[^>]*>)/gi,'$1b');

这里还有一个简短的解释:

(<\/?)strong(?=[^>]*>)

Regular expression visualization

Debuggex Demo

答案 2 :(得分:1)

您需要的RegEx是

/strong(?=>)/g

"My name is <strong>Tariq</strong>".replace(/strong(?=>)/g, "b")

Demo