2014-01-03 1 views
1

Я хочу заменить некоторые конкретные буквы (got from user input), чтобы заменить некоторые специальные теги html, например <b>,<u>,<i>,etc. Я использую некоторые регулярные выражения в javascript, но не могу определить, какие из них лучше всего использовать. Я используюКакое регулярное выражение должно использоваться для замены тегов в стиле bbcode с помощью HTML-тегов

/\[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

bbcode не является обычным языком. Вы не должны пытаться анализировать его с помощью регулярных выражений. Получите парсер bbcode из github или напишите свой собственный. – Marcos

ответ

1

Регексов не должно использоваться. Найдите достойный парсер bbcode (например, PHP BBCode) и используйте его. пытаясь разобрать HTML или любой установленный язык разметки с помощью Regex, вы просите о боли, проблемах и неуверенности.

bobince написал epic answer о разборе HTML с регулярными выражениями, что также актуально и всегда стоит прочитать.

+1

Я пытаюсь разобрать bbcode как вещи, а не html. –

+1

Я отредактировал для уточнения, но это не имеет большого значения. Вы пытаетесь написать свой собственный синтаксический анализатор для установленного языка разметки, который содержит много мелких деталей и gotchas. Просто изучите и используйте что-то, что было проверено и хорошо использовано, вы сэкономите время, и оно будет гораздо более безопасным и менее багги. – cincodenada

+0

Причина, по которой мой ответ был первоначально ориентирован на HTML, кстати, заключается в том, что ваш заголовок (до того, как я его отредактировал) подразумевал, что вы анализировали HTML. Я вернулся и отредактировал его, чтобы ссылаться на bbcode, но пропустил третью ссылку на HTML в своем ответе. – cincodenada

0

Вы спрашивали, следует ли использовать /\[u\](.*?)\[u\]/g или /\[u\]\([^\[u\]]+)\[u\]/g. Оба шаблона не разработаны с конечным тегом, что важно. [u]underlined text[/u] является BBCode

Раствор с помощью расширенного регулярное выражение может быть использование 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.) соответствия любому символу в [u]...[/u] используя dotnon-greedy

$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].

Чтобы избавиться от оставшихся бб-тегов внутри, которые не были решены, теперь мы можем легко удалить их:

$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, которые могут использовать обратный вызов в качестве замены Ent.

Смежные вопросы