Есть такой код, заменяет один раз в тексте: Код (Text): function str_replace_once($search, $replace, $text) { $pos = strpos($text, $search); return $pos!==false ? substr_replace($text, $replace, $pos, strlen($search)) : $text; } $str = 'Helo World!'; $str = str_replace_once('l', 'll', $str); // результат 'Hello World!'; подскажите как в условия добавить исключения, чтобы замены не происходили если текст будет в тегах то есть если Код (Text): $str = '<a href="(тут любая ссылка)">Helo World!</a>'; то замена не произойдет
@User123, во-первых, теги - они разные бывают. Интересуют все теги, или только <a? Во-вторых - игнорировать ли подходящий для замены текст, если он находится после тегов?
да, пропускать текст если он только в тегах <a> если после тегов нужно заменить, не важно до или после тегов, один раз заменить
@User123, или вариант: PHP: function str_replace_once($search, $replace, $text) { $tagPos2 = 0; do{ $pos = strpos($text, $search, $tagPos2); $tagPos1 = strpos($text, '<a', $tagPos2); $tagPos2 = strpos($text, '</a>', $tagPos2 + 1); var_dump($pos, $tagPos1, $tagPos2); } while($tagPos1 !== false && $tagPos2 !== false && $pos !== false && ($pos >= $tagPos1 && $pos <= $tagPos2)); return $pos !== false ? substr_replace($text, $replace, $pos, strlen($search)) : $text; }
Так по универсальнее будет. PHP: $str = preg_replace('/(<.*?>.*?)?('.$old_val.')/', '${1}'.$new_val, $str);
Никто не мешает добавить один символ. Регулярка не трогает ничего внутри тегов < вот тут > PHP: $str = preg_replace('/(<a.*?>.*?)?('.$old_val.')/', '${1}'.$new_val, $str); Я понял к чему ты. Нужно было <a>ТУТ</a> ) PHP: $str = preg_replace('/(<a.*?>.*?<\/a>.*?)?('.$old_val.')/', '${1}'.$new_val, $str);
Там подвох в том, что если совпадение не найдено, начальная позиция смещается к следующему символу текста, после чего регулярное выражение применяется заново. В результате текст и внутри тега тож заменит. PHP: $old_val = 'text'; $new_val = '----'; $str = " $old_val <a $old_val > $old_val </a> "; $str = preg_replace('/(<a.*?>.*?<\/a>.*?)?('.$old_val.')/', '${1}'.$new_val, $str); Решить можно с помощью (*SKIP) и (*FAIL) http://pcre.org/original/doc/html/pcresyntax.html#SEC23 PHP: $str = preg_replace('~'.$old_val.'|<a.*?</a>(*SKIP)(*F)~s', $new_val, $str);
Там не в этом причина, если даже регулярку (<a.*?>.*?<\/a>.*?) заменить на пустые скобки () результат будет тот-же: PHP: $old_val = 'text'; $new_val = '----'; $str = " $old_val <a $old_val > $old_val </a> "; echo preg_replace('/()('.$old_val.')/', '${1}'.$new_val, $str); //---- <a ---- > ---- </a>