LINUX.ORG.RU

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


0

0

Пишу на Perl:

Есть html файл в нем надо заменить все слова $word="some"; на "<b>$word</b>" но так, чтобы не портить HTML теги, т.е. если после того что нашли есть '>' то не надо заменять, а если после есть '<' то заменять, а если нет ни '>' ни '<' - то файл кончился и надо заменить... Я пишу: foreach $lines(@file) { $lines =~ s/($word)/<b>\1<\/b>/; } это работает, но портит теги...

делал так: $lines =~ s/($word)(?!.*>)(?=.*<)/<b>\1<\/b>/i;

это заменяет "some <test", но не заменяет "some <test>"

Зарание спасибо!

anonymous

Я сделал так: $lines =~ s/($word)([^>]+)([<]+)/<b>\1<\/b>\2\3/i;

это работает, но не сраватывает если просто строка "some dfsd sdf", как это можно решить?

anonymous
()

а можно в студию пример текста со всеми фишками, которые надо заменить?
ну и соответственно пример текста, с замененными фишками?

$lines =~ s/($word)([^>]+)([<]+)/<b>\1<\/b>\2\3/i;

вообще, знак вопроса перед символом или группой символов(заданных явно 
 или регекспом) означает по смыслу "если есть". Иными словами, "somex" 
и "some x" регексп s!(somex?)!<b>$1</b>! по идее заменит на "<b>somex</b>" 
и "<b>some</b> x" соответственно.

vilfred ☆☆
()

Почему просто не написать $word=some;s/$word(?=[^>]*<|[^<>]*$)/<b>$&<\/b>/g ?

anonymous
()

>>а можно в студию пример текста со всеми фишками, которые надо заменить?

есть файл такого содержания:
>>start>

<td>
<br>
<font color="здесь" size=2>

<a href=http://www.ru?здесь> голосования для Вашего сайта</a>.
Только здесь статистика голосов по городам и времени.
<P>02.01.2003
<BR>
Проведена чистка - удалены адреса, неиспользуемые больше полугода.
<P>
20.08.2002
<BR>
здесь test
la la la

>>end>

Надо в нем заменить все слова "здесь" на "<b>здесь</b>" а перед первым вхождением поставить: "<a name=#link><a/>" чтобы туда потом браузер прокрутку сделал.

Т.е. должно быть:
>>start>

<td>
<br>
<font color="здесь" size=2>

<a href=http://www.ru?здесь> голосования для Вашего сайта</a>.
Только <a name=#link><a/><b>здесь</b> статистика голосов по городам и времени.
<P>02.01.2003
<BR>
Проведена чистка - удалены адреса, неиспользуемые больше полугода.
<P>
<b>ЗДЕСЬ</b> 20.08.2002
<BR>
<b>Здесь</b> test
la la la

>>end>


>>Почему просто не написать $word=some;s/$word(?=[^>]*<|[^<>]*$)/<b>$&<\/b>/g ?

спасибо - это работает, а как бы первым вхождением поставить: "<a name=#link><a/>"?

anonymous
()

Не понял про первое вхождение

anonymous
()

Что-нибудь вроде $first=1; ...цикл... if ( /$word/ && $first) { $first=0; s/$word//<a>...$word/}?

anonymous
()

>>Не понял про первое вхождение

>>Что-нибудь вроде $first=1; ...цикл... if ( /$word/ && $first) { $first=0; s/$word//<a>...$word/}?

да именно так, я вчера где-то читал про это, но сейчас не могу найти.

Надо чтоб:

Было: test r Test asdasd TEST
Стало: <a name=#link><a/><b>test</b> r <b>Test</b> asdasd <b>TEST</b>

Подскажите как?

anonymous
()

s/test/<a name=#link><a/>$&/i; перед заменой которая добавляет <b>. Просто ключ g не ставим и правило заменит только первое вхождение в строке

anonymous
()

Спасибо, работает. Возник ещё вопрос:

Я хочу заменить это во всем файле, пишу: ---- open(FILE2, "<$file") || &debug("Can't open: $!"); @wholefile = <FILE2>; close(FILE2); foreach $lines(@wholefile) {

$lines =~ s/$word/<a name=#link><\/a>$&/i; $lines =~ s/$word(?=[^>]*<|[^<>]*$)/<b>$&<\/b>/ig; } print "---\n"; print "@wholefile"; print "---\n"; ---- происходит замена в каждой строчке по отдельности(что и понятно), но ведь может же быть "\n\n some \n\n > text" - а это не надо заменять, можно ли как-нибуь сделать чтоб шла замена во всем файле не производя: --- foreach $lines(@wholefile) { $lines_big.=$lines; } а потом $lines_big =~ s/$word/<a name=#link><\/a>$&/i; $lines_big =~ s/$word(?=[^>]*<|[^<>](?=[^>]*<|[^<>]*$)/<b>$& <\/b>/ig;

print $lines_big; --- ???

И ещё: не работает игнорирование регистра с русскими символами, можно ли это как-нибудь исправить?

anonymous
()

По поводу "и еще" - исправить можно. Но это уже наглость. Надо хоть иногда делать свою работу самому.

anonymous
()

козлы помочь не можите

anonymous
()

помочь то можем. но за "козлы" только два совета:

1) $/=undef; open F, "<file.ext"; $f=<F>; close F; откроет файл в переменную. и во все регекспы надо вставить ключ s или m я не помню

2) чтобы сделать a name только в первом вхождении, нужно замену s!!! провести без ключа s!!!g. который значит, что надо провести все замены не включая первый...

vilfred ☆☆
()

вообще, делать s!!! в цикле foreach конечно можно, но тут проще через $/=undef, потому что не будет вопросов типа "как выделить и заменить первое вхождение подстроки в строку(так как тут строка будет всем html файлом)". заодно и избавляешься от лишнего цикла foreach

д.

vilfred ☆☆
()

>>помочь то можем. но за "козлы" только два совета
сообщение от "anonymous (*) (2003-08-05 13:17:49.88434)" писал НЕ Я, я только что вернулся в форум после того как написал "anonymous (*) (2003-08-05 13:09:35.225431)"

>>1) $/=undef; ...
работает, а что делает "$/=undef"?
Я пытался так делать только без $/=undef в итоге получил только первую строчку из файла.

>>2) чтобы сделать a name только...
Я делаю:
$f =~ s/$word/<a name=#link><\/a>$&/i;
$f =~ s/$word(?=[^>]*<|[^<>]*$)/<b>$&<\/b>/ig;
это работает, имелось ввиду это?


Почему не работает игнорирование регистра с русскими символами, можно ли это как-нибудь исправить?

anonymous
()

1) когда ты открываешь файл и пишешь его содержимое в массив, то в каждом элементе массива содежрится строка. Встроенная переменная $/ это тот самый разделитель, который определяет строку. если этот разделитель переопределить, то у тебя будет многострочкая переменная(где разделителем строки является \n и по этому \n и происходит занесение строк в массив), но с точки зрения перла это будет одна строчка, если $/=undef;

если $/='<p>' то файл будет разделяться по абзацам.

2) "это работает, имелось ввиду это?" ну примерно это, яб покороче написал, на там думать надо, а это лениво... но впрочем если работает то и хорошо.

3) "Почему не работает игнорирование регистра с русскими символами, можно ли это как-нибудь исправить?" поставь после строки #!/usr/bin/perl -w строку use locale;

vilfred ☆☆
()

Если можно предложите, пожалуйста, вариант "покороче". Лично я таких не знаю

anonymous
()

Большое спасибо за объяснение.

>>3) "Почему не работает игнорирование регистра с русскими символами, можно ли это как-нибудь исправить?" поставь после строки #!/usr/bin/perl -w строку
use locale;

я это пробовал, но это не помогает, наверное у меня не правильно настроена локаль...
Кстати что подразумевается под локалью - отображение символов?
как её настроить правильно?

anonymous
()

Это было очевидно с самого начала... Я поэтому про прагмы и не стал объяснять. Теперь надо LC_CTYPE установить

anonymous
()

Спасибо всем за ответы! Со всем разобрался, всё работает!

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.