Ну, эта часть неверна:
(["'])(?:\\\1|[^\1])*?\1
Это должно соответствовать последовательности, заключенной в одинарные или двойные кавычки, возможно, включая кавычки с обратной косой чертой. Но это не сработает, потому что обратные ссылки не работают в классах персонажей. \1
обрабатывается как число 1
в восьмеричной записи, поэтому [^\1]
соответствует любому символу, кроме U + 0001 .
Если кажется, что он работает большую часть времени, это из-за неохотного квантификатора (*?
). Первая альтернатива в (?:\\\1|[^\1])*?
правильно использует экранированную кавычку, но в противном случае она просто неохотно соответствует любому символу, пока не увидит не экранированную кавычку. Это хорошо работает с правильно сформированным текстом, но добавьте дополнительную цитату, и она станет бесполезной.
Правильный способ сопоставления «чего-либо, кроме захваченной группы № 1» - это (?:(?!\1).)*
, то есть использовать по одному символу за раз, но только после того, как предварительный просмотр подтвердит, что это не первый символ захваченного текста. Но я думаю, что вам будет лучше иметь дело с каждым видом цитаты отдельно; это регулярное выражение достаточно сложно, как есть.
'~<(?!/?+(?:'.implode('|',$white).')\b)[^\s>]++(?:\s++'.
'(?:[^\'">]++|"(?:[^"\\]++|\\")*+"|\'(?:[^\'\\]++|\\\')*+\')*+)?+>~'
Обратите внимание на добавление \b
(границы слова) после чередования белого списка. Без этого, если у вас есть (например) <B>
в вашем списке, вы также непреднамеренно добавите в белый список теги <BODY>
и <BLOCKQUOTE>
.
Я также везде использовал притяжательные квантификаторы (*+
, ++
, ?+
), потому что способ написания этого регулярного выражения, я знаю, обратный просмотр никогда не будет полезным. Если он потерпит неудачу, я хочу, чтобы он потерпел неудачу как можно быстрее.
Теперь, когда я рассказал вам, как заставить регулярное выражение работать, позвольте мне убедить вас не использовать его. Эта работа слишком сложна и слишком важна, чтобы ее можно было выполнить с помощью такого плохо подходящего инструмента, как регулярное выражение. И если вы действительно получили это регулярное выражение из книги по безопасности PHP, я предлагаю вам вернуть свои деньги.