使用正则表达式替换块中的特殊字符

时间:2012-10-04 12:14:58

标签: javascript regex

我需要更换所有<和>在[code]块之间。我不想选择和替换[code]中的所有内容我只想选择<和>在其中,然后临时将其替换为另一个角色。做其他更换,然后将它们退回到< >在[代码]中。

我使用的解决方案:

replace(/<(?=[^\[]*\[\/code\])/gi,"&_lt_;"); 
replace(/>(?=[^\[]*\[\/code\])/gi,"&_gt_;"); 

DO OTHER REPLACEMENT/CUSTOMIZATION HERE 

replace(/&_lt_;/gi,"<"); 
replace(/&_gt_;/gi,">"); 

唯一的问题是,如果[code]之间的内容包含字符[它在块中的该字符之前不起作用。我该如何解决这个问题?

有效的例子:

<b>
[code]
<form action="nd.php" method="post">
<b>
<strong>
[/code]
<b>

不起作用的示例:

<b>
[code]
<form action="nd.php" method="post">
<b>
$_POST[
<strong>
[/code]
<b>

编辑:请仅提供简单的正则表达式替换解决方案。我不能使用回调函数来解决这个问题。

2 个答案:

答案 0 :(得分:1)

对于“有效的示例”,链接问题的已接受答案对我不起作用。但是,的其他答案 - 它也适用于“不起作用的示例”(虽然有一个错字)。

尝试以下正则表达式:

/(\[code\][\s\S]*?\[\/code\])|<[\s\S]*?>/g

replace()函数中,您将使用:

.replace(/(\[code\][\s\S]*?\[\/code\])|<[\s\S]*?>/g, '$1'); 

修改
如果我理解正确,您的最终目标是保持[code][/code]内的所有内容相同 - 但是能够替换外的所有HTML标记这些标签(可能是也可能不意味着完全剥离字符)?

如果是这种情况,则不需要很长的正则表列表;可以使用上面的正则表达式(略有修改),它可以涵盖很多情况。将正则表达式/替换与回调函数结合起来处理额外的替换:

var replaceCallback = function(match) {
    // if the match's first characters are '[code]', we have a '[code][/code]' block
    if (match.substring(0, 6) == '[code]') {
        // do any special replacements on this block; by default, return it untouched
        return match;
    }
    // the match you now have is an HTML tag; it can be `<tag>` or `</tag>`
    // do any special replacements; by default, return an empty string
    return '';
}

str = str.replace(/(\[code\][\s\S]*?\[\/code\])|(<[\s\S]*?>)/g, replaceCallback);

一个正则表达式修改是在html-tag部分(正则表达式的第二部分)周围添加一个组。这将允许它传递给回调函数。

更新[code]不是文字)
根据评论,我意识到标签[code]不是文字的 - 您想要涵盖所有BBCode样式标签。这与上面的示例一样简单(在回调中更容易)。您可以使用code来覆盖所有字母字符,而不是正则表达式中的单词[a-z]+。然后,在回调中你可以检查第一个字符;如果它是[,则表示您处于代码块中 - 否则您的代码块外部会出现HTML标记:

var replaceCallback = function(match) {
    // if the match's first character is '[', we have a '[code][/code]' block
    if (match.substring(0, 1) == '[') {
        // do any special replacements on this block; by default, return it untouched
        return match;
    }
    // the match you now have is an HTML tag; it can be `<tag>` or `</tag>`
    // do any special replacements; by default, return an empty string
    return '';
}

str = str.replace(/(\[[a-z]+\][\s\S]*?\[\/[a-z]+\])|(<[\s\S]*?>)/gi, replaceCallback);

另请注意,我在正则表达式的选项中添加了i以忽略大小写(否则您需要[a-zA-Z]来处理大写字母)。

答案 1 :(得分:1)

这是我编辑的答案。对不起。

str = str.replace(/(\[code\])(.*?)(\[\/code\])/gm,function(a,b,c,d) {
    return b + c.replace(/</g,'&lt;').replace(/>/g,'&gt;') + d;
});