Помогите регулярным выражением

М
На сайте с 08.09.2006
Offline
223
591

Всем привет.

Помогите, пожалуйста, решить задачку.

Пример:

<p><a href="text">text</a> text</p>

нужно заменить текст: text на newtext, но при этом чтобы все что внутри тега <a> не подавлось замене. То есть на выходе должно получиться так:

<p><a href="text">text</a> newtext</p>

Нужна регулярка по которой можно было производить данную замену по всему тексту.

При этом вместо тегов <p> могут быть любые другие теги, <div>, <td> и так далее. Суть в том, чтобы исключить замену в теге <a> и в его атрибутах.

Спасибо)

Не бойся неизбежного... Уже не продаю авто морды...
gormarket
На сайте с 29.12.2010
Offline
47
#1

Вот регулярка

'~text</a> text~'

а вот текст для замены

'text</a> newtext'

Товары и цены в магазинах Вашего города: Городской рынок (http://gormarket.ru/)
М
На сайте с 08.09.2006
Offline
223
#2
gormarket:
Вот регулярка
'~text</a> text~'
а вот текст для замены
'text</a> newtext'

Это не по подходит, а если текст, который нужно заменить находится не сразу после закрывающего тега <a> ? Я привел лишь пример, суть в том, что нужно заменить все патерны за исключенем тех что находятся внутри тега <A>.

Если будет исходный текст такой:

<p><a href="text">text</a> БЛА БЛА БЛА text</p>

То ваша вариант решения уже не поможет.

gormarket
На сайте с 29.12.2010
Offline
47
#3

Можно сделать и расширенный вариант (это пример для PHP):

$t='<p><a href="text1">text1</a> text</p> <p><a href="text">text</a> bla bla 1 text bla bla 2</p>';

$t1= preg_replace('~(text)</a>(.*)\\1(.*)<~','\\1</a>\\2newtext\\3<',$t);

print htmlspecialchars($t).'<br/>';

print htmlspecialchars($t1);

Результат будет такой:

<p><a href="text1">text1</a> text</p> <p><a href="text">text</a> bla bla 1 text bla bla 2</p>

<p><a href="text1">text1</a> text</p> <p><a href="text">text</a> bla bla 1 newtext bla bla 2</p>

P.S.

В этом варианте необходимо еще добавить в регулярное выражение модификатор, делающий выражение "нежадным" (чтоб не захватывалось лишнего)

$t1= preg_replace('~(text)</a>(.*)\\1(.*)<~U','\\1</a>\\2newtext\\3<',$t);

М
На сайте с 08.09.2006
Offline
223
#4
gormarket:
Можно сделать и расширенный вариант (это пример для PHP):

$t='<p><a href="text1">text1</a> text</p> <p><a href="text">text</a> bla bla 1 text bla bla 2</p>';
$t1= preg_replace('~(text)</a>(.*)\\1(.*)<~','\\1</a>\\2newtext\\3<',$t);
print htmlspecialchars($t).'<br/>';
print htmlspecialchars($t1);


Результат будет такой:

<p><a href="text1">text1</a> text</p> <p><a href="text">text</a> bla bla 1 text bla bla 2</p>
<p><a href="text1">text1</a> text</p> <p><a href="text">text</a> bla bla 1 newtext bla bla 2</p>

P.S.
В этом варианте необходимо еще добавить в регулярное выражение модификатор, делающий выражение "нежадным" (чтоб не захватывалось лишнего)
$t1= preg_replace('~(text)</a>(.*)\\1(.*)<~U','\\1</a>\\2newtext\\3<',$t);

А что означает в вашм вариенте 1, 2 и 3? Это как некие идентификаторы идут? Ведь в реальном тексте их не будет, а нужна реализация для любых материалов.

R
На сайте с 06.02.2011
Offline
62
#5
siv1987
На сайте с 02.04.2009
Offline
427
#6

По нормальному это делается немного по другому, заменяются все анкоры на некие идентификаторы, а сами помещаются в массив. Заменяется текст в строке. Обратно востанвливаются ан коры из массива (или ссылки целиком). Одним регулярным выражением не знаю если сможете обойтись.

М
На сайте с 08.09.2006
Offline
223
#7
siv1987:
По нормальному это делается немного по другому, заменяются все анкоры на некие идентификаторы, а сами помещаются в массив. Заменяется текст в строке. Обратно востанвливаются ан коры из массива (или ссылки целиком). Одним регулярным выражением не знаю если сможете обойтись.

Да, была такая идея. Но при таком варианте мы потеряем регистры. Либо нужно заводить разные идентификаторы для каждого варианта написания одного слова.

FollowLocation
На сайте с 19.07.2013
Offline
12
#8

Маэстро,

$text = preg_replace_callback ('|(<a.+?\/a>)|si', create_function('$matches', 'return "#a#".base64_encode($matches[0])."#/a#";' ), $text);
$text = str_replace ('text', 'newtext', $text);
$text = preg_replace ('|(#a#)(.+?)(#\/a#)|sie', "base64_decode('$2')", $text);

Кодируем все теги <a> в base64, затем производим замену, затем декодируем <a> обратно

siv1987
На сайте с 02.04.2009
Offline
427
#9
Маэстро:
Но при таком варианте мы потеряем регистры.

Ничего при таком варианте не теряется, регистр остается такой как есть. Либо таким вариантом с басе64 как посоветовали выше

М
На сайте с 08.09.2006
Offline
223
#10
FollowLocation:
Маэстро,
$text = preg_replace_callback ('|(<a.+?\/a>)|si', create_function('$matches', 'return "#a#".base64_encode($matches[0])."#/a#";' ), $text);

$text = str_replace ('text', 'newtext', $text);
$text = preg_replace ('|(#a#)(.+?)(#\/a#)|sie', "base64_decode('$2')", $text);


Кодируем все теги <a> в base64, затем производим замену, затем декодируем <a> обратно

Спасибо, попробую такой вариант отпишу по итогам.

---------- Добавлено 30.09.2013 в 00:08 ----------

FollowLocation:
Маэстро,
$text = preg_replace_callback ('|(<a.+?\/a>)|si', create_function('$matches', 'return "#a#".base64_encode($matches[0])."#/a#";' ), $text);

$text = str_replace ('text', 'newtext', $text);
$text = preg_replace ('|(#a#)(.+?)(#\/a#)|sie', "base64_decode('$2')", $text);


Кодируем все теги <a> в base64, затем производим замену, затем декодируем <a> обратно

Cпасибо большое, работает

Авторизуйтесь или зарегистрируйтесь, чтобы оставить комментарий