Вот часть кода из xss_clean метода класса Input_Core платформы Kohana:
do
{
// Remove really unwanted tags
$old_data = $data;
$data = preg_replace('#</*(?:applet|b(?:ase|gsound|link)|embed|frame(?:set)?|i(?:frame|layer)|l(?:ayer|ink)|meta|object|s(?:cript|tyle)|title|xml)[^>]*+>#i', '', $data);
}
while ($old_data !== $data);
Является... необходимым циклом с условием продолжения? Я думал бы, что вызов preg_replace выполнит во всей работе всего одно повторение.
Ну, это необходимо, если замена потенциально создает новые совпадения в следующей итерации. Это не очень расточительно, потому что в худшем случае это только дополнительная проверка.
Судя по коду, который он подбирает, кажется маловероятным, что он создаст новые соответствия при замене, однако: он очень строг к тому, что он подбирает.
EDIT: Чтобы быть более конкретным, он пытается найти соответствие открывающей угловой скобке, за которой может следовать слэш, за которым следует одно из нескольких ключевых слов, за которым может следовать любое количество символов, не являющихся закрывающей угловой скобкой, и, наконец, закрывающая угловая скобка. Если входные данные соответствуют этому синтаксису, они будут проглочены целиком. Если он неправильно сформирован (например, много открывающих и закрывающих угловых скобок), он будет генерировать мусор до тех пор, пока не сможет найти подстроки, соответствующие исходной последовательности.
Так что, нет. Если только у вас нет кода вроде <
, повторения не нужны. Но тогда вы имеете дело с уровнем супа тегов, для которого регекс все равно недостаточно хорош (например, он не справится с < iframe>
с лишним пробелом).
EDIT2: Также немного странно, что шаблон соответствует нулю или более слешей в начале тега (должно быть ноль или один). И если мои познания в регексе еще не слишком проржавели, то финальный *+
тоже не имеет особого смысла (звездочка означает ноль или больше, плюс - один или больше, может это жадный синтаксис или что-то подобное?).
По совершенно не связанной теме, я хотел бы добавить пару слов по оптимизации здесь.
preg_replace () может сказать вам, была ли произведена замена или нет (см. 5-й аргумент, который передается по ссылке). Это намного эффективнее, чем сравнение строк, особенно если они большие.