我想替换某些特定字母(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
攻击是安全的。
答案 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可以使用回调作为替代。