2014-01-03 3 views
0

У меня есть белый список конечных тегов HTML (br, b, i, div): -Почему регулярное выражение соответствует строке, когда другие присутствуют?

String whitelist = "([^br|^b|^i|^div])"; 
String endTagPattern = "(<[ ]*/[ ]*)" + whitelist + "(>?).*?([^>]+>)"; 
... 
html = html.replaceAll(endTagPattern, "[r]"); 

Который берет мой тест String и удаляет конечные теги тех, кто не в белом списке, в этом случае заменен [r] для ясности: -

1. <b>bold</b>, 2. <i>italic</i>, 3. <strong>strong</strong>, 4. <div>div</div>, 5. <script lang='test'>script</script> 
1. <b>bold</b>, 2. <i>italic</i>, 3. <strong>strong[r], 4. <div>div</div>, 5. <script lang='test'>script[r] 

Если добавить strong в этот белый список

String whitelist = "([^br|^b|^i|^div|^strong])"; 

Он не только не совпадает с конечным тегом strong, но также останавливается, соответствуя теге конца script или любому другому в этом отношении.

Мой вопрос: почему?

+1

[Этот ответ может быть уместным] (http://stackoverflow.com/a/1732454/2071828). Вы также не понимали, как работает регулярное выражение - шаблон '[^ br |^b |^i |^div |^strong]' является группой символов, которая соответствует ** не ** 'b' или' r' или '| 'или' d' или 'i' и т. д. ... –

+0

Я понимаю, что синтаксический анализ HTML любым сложным способом является болезненным, если не невозможным, но должно быть возможно удалить теги здесь и там нет? –

+1

(1) Использование HTML и регулярное выражение - действительно плохая идея. Вместо этого вы должны использовать парсер. (2) Кажется, вы путаете [группы] (http://www.regular-expressions.info/brackets.html) '(...)' и [классы символов] (http: //www.regular-expressions .info/charclass.html) '[...]'. – Pshemo

ответ

1
String whitelist = "([^br|^b|^i|^div])"; 

Использование [] создает класс символов. Я полагаю, вы написали это, так что вы можете использовать ^ для «не», но класс символов здесь не подходит. В квадратных скобках | не означает «или»; это просто буквальный характер трубы. И письмо div не соответствует словоdiv, оно соответствует одному из трех символов, d, i, или v. Отрицая, что означает «соответствовать ничего, кроме d, i или v.

Это белый список фактически эквивалентно [^bdirv|\^] — он соответствует одному символу, который не b, d, i, r, v, | или ^.

String whitelist = "(?!br|b|i|div)"; 

Если вы хотите, чтобы исключить определенные матчи, что вы хотите negative lookahead. Опуская квадратные скобки позволяет использовать | так, как вы предполагали, в качестве оператора «или».

+0

Ваш белый список действительно работает :) –

4

Причина в том, что вы используете класс символов. Внутри класса символов порядок символов не имеет значения, кроме случаев, когда вы имеете дело с диапазонами символов.

Так, [^br|^b|^i|^div|^strong] на самом деле будет соответствовать любому символу, за исключением тех:

bridvstrong|^ 

[Обратите внимание, что | и ^ там тоже].

Возможно, вы использовали [^bridvstrong|^], и он будет вести себя одинаково.

Вы можете вместо этого взглянуть на негативные взгляды.

+2

Ah phooey, подумал, что мне придется делать импорт с помощью простого регулярного выражения. Я ошибся, я выучил свой урок. Для меня больше HTML и Regexing. –

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