应使用哪个正则表达式用HTML标记替换bbcode样式标记

时间:2014-01-03 20:04:21

标签: javascript php html regex bbcode

我想替换某些特定字母(got from user input)以替换某些特定的html标签,例如<b>,<u>,<i>,etc。我在javascript中使用了一些regexps,但无法确定哪种用法最好。我正在使用

/\[u\](.*?)\[u\]/g // replace with <u>$1</u>
/*
 * if i type [u]underline[][u] //this allows '[]' braces
*/

或者我应该使用

/\[u\]\([^\[u\]]+)\[u\]/g // this doesn't allow third braces to be underlined

我也在php中使用相同的正则表达式。我很困惑哪种类型的正则表达式使用xss攻击是安全的。

2 个答案:

答案 0 :(得分:1)

不应使用正则表达式。找一个像样的bbcode解析器(例如,PHP的BBCode)并使用它。试图用Regex自己解析HTML或任何已建立的标记语言是在寻求痛苦,麻烦和不安全感。

bobince编写了一篇关于使用正则表达式解析HTML的epic answer,这里也很重要,并且总是值得一读。

答案 1 :(得分:0)

您询问是否使用/\[u\](.*?)\[u\]/g/\[u\]\([^\[u\]]+)\[u\]/g。两种模式都没有设计结尾标记,这很重要。 [u]underlined text[/u]BBCode

使用扩展正则表达式的解决方案可能是{strong>使用recursive patterns 。我认为有no support in JavaScript yet,但效果正常,例如 PHP ,它使用PCRE

问题:标签可以嵌套,这样就很难与最外面的标签相匹配。


理解这个PHP示例中的以下模式:

$str = 
'The [u][u][u]young[/u] quick[/u] brown[/u] fox jumps over the [u]lazy dog[/u]';

1。)使用dot non-greedy

匹配[u]...[/u]中的任何字符
$pattern = '~\[u\](.*?)\[/u\]~';
$str = preg_replace($pattern, '<u>\1</u>', $str);
echo htmlspecialchars($str);

输出

The <u>[u][u]young</u> quick[/u] brown[/u] fox jumps over the <u>lazy dog</u>

查找[u]的第一次出现并尽可能少地使用字符来满足条件[/u],从而导致标记不匹配。所以这是一个糟糕的选择。


2。)使用negation方括号 [^[\]]了解[u]...[/u]内的内容

$pattern = '~\[u\]([^[\]]*)\[/u\]~';
$str = preg_replace($pattern, '<u>\1</u>', $str);
echo htmlspecialchars($str);

输出

The [u][u]<u>young</u> quick[/u] brown[/u] fox jumps over the <u>lazy dog</u>

它会查找[u]的第一次出现,然后是[]符合条件[/u]的任意数量的字符。它“更安全”,因为它只匹配最里面的元素,但仍需要额外的努力才能从内到外解决这个问题。


3。)使用方括号[^[\]]的递归 + negation作为[u]...[/u]内的内容

$pattern = '~\[u\]((?:[^[\]]+|(?R))*)\[/u\]~';
$str = preg_replace($pattern, '<u>\1</u>', $str);
echo htmlspecialchars($str);

输出

The <u>[u][u]young[/u] quick[/u] brown</u> fox jumps over the <u>lazy dog</u>

与第二种模式类似:查找[u]的第一次出现,但随后匹配一个或多个不是[]paste the whole pattern的字符在(?R)。整个事情是零次或多次,直到条件[/u]匹配。

为了摆脱内部剩余的bb-tag,我们现在可以轻松删除它们了:

$str = preg_replace('~\[/?u\]~',"",$str);

并按照需要得到它:

输出The <u>young quick brown</u> fox jumps over the <u>lazy dog</u>

肯定有不同的实现方法,例如preg replace callback或JavaScript replace() method可以使用回调作为替代。