WebScript.Ru
C:\   главная  ::   о сайте  ::  каталог скриптов  ::  гнездо  ::  форум  ::   авторам  :: Новостройки ::   ХОСТИНГ  ::

|| разделы::
|| поиск по сайту::

|| реклама::
|| новости почтой::
Рассылки Subscribe.Ru ::



Новости сайта WebScript.Ru
Популярные статьи

Hot 5 Stories

|| рекомендуем::




Кавычки и regular expressions


Прислал: Spectator [ 21.05.2001 @ 17:06 ]
Раздел:: [ Статьи по PHP ]


Поначитался я на разных сайтах про кавычки. Вот тут, например, или вот тут. Дескать, кавычки нужны только вот такие - « и вот такие - », а никак не такие - '', и все остальное - от лукавого!

Сел, стал думу думать, как бы так сделать, чтобы в тексте кавычки вот такие - '' сами (с помощью маленького php-скрипта) заменялись на нужные «елочки». Ясное дело - regular expressions, как же без них. Решил заодно и regular expressions освоить, а то пока как-то не доводилось сталкиваться с ними очень близко... Проблемы две: первая - чтобы кавычки чередовались правильно, открывающая кавычка - «, а закрывающая - », и никак не наоборот; вторая - чтобы в html-тэгах они даже и не думали меняться. Ни-ни.

В общем, думал я минут десять...

Желающие могут не читать дальше, а подумать сами, а потом сравнить полученный результат с моим.

Думал я минут десять... Потом понял, что думаю не туда. На самом деле все гораздо проще.

Первое. Ищем сначала открывающие кавычки. В нормальном тексте перед ними стоит проблел. Всегда. Почти. В общем, - как правило. Если пробела нет, то текст просто неграмотно набран, мы такие запущенные случаи рассматривать не будем. Итак,

$contents = str_replace (" ""," «", $contents);
// ищем в тексте проблел с кавычками и заменяем его на пробел с открывающейся елочкой - «

Кроме пробела, открывающая кавычка может быть сразу после новой строки, верно? Ищем и ее:

$contents = str_replace ("n"","«", $contents);

Таким образом html-тэги не попадают под этот поиск и замену, потому что в них не бывает такого, чтобы перед кавычкой стоял пробел.

Есть еще случай, когда кавычка стоит после закрытия тэга, например <b>«Типа текст»</b>. Ищем и этот случай:

$contents = str_replace (">"",">«", $contents);

Итого имеем три строчки кода, которые ищут и заменяют открывающуюся кавычку:

$contents = str_replace (" ""," «", $contents);
$contents = str_replace ("n""," «", $contents);
$contents = str_replace (">"",">«", $contents);

Почему str_replace, а не ereg_replace? Потому что эти три строчки со str_replace в данном случае быстрей одной с ereg_replace в несколько раз. RTFM, как говорится. А вот дальше без ereg_replace не обойтись.

Итак...

...начинаем искать с открывающейся кавычки («). Раз мы начинаем искать с нее, html-тэги автоматически исключаются (смотри выше - почему) :

$contents = ereg_replace ('«

ищем последовательность символов (то есть [...]* ), в которую не входит (то есть ^) вот такая - '' кавычка:

([^"]*)"'

И заменяем эту последовательность, то есть 1 на эту последовательность в кавычках: «1»:

,"&laquo;1&raquo;", $contents);

Для еще лучшей работы в конце стоит добавить еще и $contents = str_replace ("«","&laquo;", $contents);. Можно, конечно, делать это в первых трех строчках, но у меня тогда ereg_replace работал дольше и глючил...

Итого:

$contents = str_replace (" ""," «", $contents);
$contents = str_replace ("n""," «", $contents);
$contents = str_replace (">"",">«", $contents);
$contents = ereg_replace ('«([^"]*)"',"&laquo;1&raquo;", $contents);
$contents = str_replace ("«","&laquo;", $contents);

Коротко и ясно...

... ну ладно, просто «коротко»...

Как и полагается - known bugs. Известные ошибки. Если на вашем сайте размещаются примеры скриптов, (как у меня, например) то могут быть проблемы в том случае, если где-то в теле скрипта после пробела стоит кавычка. Решение - &nbsp; перед кавычкой. Либо думайте сами. (С html-ем и примерами из него проблем нет).

Еще баг: «//spectator.ru«.

И еще один - когда кавычки в кавычках: «И он сказал: «Я пришел к вам...», - ну и так далее". Самая последняя кавычка обрабатывается некорректно.

PS. Данный пример описан и сделан только в качестве развлечения для автора, он (автор) ни в коем случае не уговаривает никого переходить на такие « » кавычки. Исправления принимаются.


В качестве бонуса. Начав оставаивать regular expressions, сделал себе нормальную версию для печати, вот например. Могу поделиться кусочком скрипта:

<?php
// $con - это текст статьи

$con = str_replace('</a>','¬',$con);
$con = eregi_replace('<a[^h]*href=["]*(//[^">]*)[^>]*>([^¬]*)¬', '2 ( <u><font color=blue>1</font></u> )',$con);
// меняем ссылки на другие сайты

$con = ereg_replace('<a[^h]*href=["]*([^">]*)[^>]*>([^¬]*)¬'," 2 ( <u><font color=blue>//$HTTP_HOST/1</font></u> )", $con);
// меняем локальные ссылки

echo $con; ?>


Еще одна "Regular expression", спер где-то. Делает простую вещь - пролинковывает в тексте ссылки. То есть было //spectator.ru, стало - //spectator.ru.

$text = eregi_replace("([[:alnum:]]+)://([^[:space:]]*)([[:alnum:]#?/&=])","<a href="1://23">1://23</a>",$text);

Вот и все.


 :::::  Spectator пишет 21.05.2001 @ 19:13 
Немного поколдовал. Этот вариант лишен двух багов - когда внутри кавычек содержатся тэги и бага с кавычками внути кавычек.

$contents = str_replace (" \""," «", $contents);
$contents = str_replace ("\n\""," «", $contents);
$contents = ereg_replace ('«([^"]*)"',"&laquo;\\1&raquo;", $contents);
$contents = str_replace (">\"",">«", $contents);
$contents = ereg_replace ('«([^"]*)"',"&laquo;\\1&raquo;", $contents);
$contents = str_replace ("«","&laquo;", $contents);

Работает примерно на 7% медленней. У кого есть добавления - присылайте.

 :::::  Lion пишет 21.05.2001 @ 22:22 
Ошипок много...
 :::::  Konstantin пишет 22.05.2001 @ 23:49 
Дим, оченно рад, что у тебя наконец-то и это поправится :)

Да, и еще пожелание – вот «ачепяток» в статьях поменьше бы... Опять-таки смайлик!
 :::::  Spectator пишет 23.05.2001 @ 12:23 
Кстати, там же (http://www.redactor.ru/replic/alt.shtml) написано:

То и дело вместо тире в интернете можно видеть знак дефиса (минус в верхнем ряду клавиатуры), что неверно; либо – два подряд дефиса, что не необходимо. Код длинного тире (в полиграфии его называют Em Dash, т. е. «тире шириной с букву m») – Alt-0151. Чтобы его набрать, нужно прижать кнопку Alt и, не отпуская, набрать на цифровой** клавиатуре 0151.
Замену «неправильных» тире на правильные можно сделать совсем просто – «правильные» тире – это те, которые с двух сторон окружены пробелы. Их и меняем на «Em Dash».


$con = str_replace (" - "," – ", $con);


2Konstantin: Кость, здесь все-таки не мой фан-клуб ;) Все такие отзывы - мне на сайт.


 :::::  NoNaMe пишет 25.05.2001 @ 06:18 
М-м-м-м-м..... да-а-а-а....
и многим, интересно мне знать, это надо????
разные кавычки?
 :::::  dina пишет 13.06.2001 @ 09:32 
вот именно...
это все хорошо, но по-моему чем проще, тем лучше..

какая разница... какие ковычки? только время лишнее пользователю ждать и сервер загружать...
 :::::  bang пишет 13.06.2001 @ 13:25 
Ну, кому-то и знаки препинания не нужны...
 :::::  bang пишет 15.06.2001 @ 04:05 
Я вчера как раз такую штучку сделала - для тех, кто сам не может написать для себя обработчик текстов на PHP - bang.dax.ru
Заменяет кавычки, тире, аопстрофы и т.п. на их коды для корректного вывода в HTML.

 :::::  Майк пишет 08.11.2002 @ 05:46 
Если кому в лом включать _цифровую_ клавиатуру, можно просто набрать &#151; - вот вам и длинное тире :)
 :::::  tven пишет 02.12.2003 @ 12:05 
А если вот такое регулярное выражение применить:
$str=preg_replace("|([^\=])\"([[:alpha:],\-,\s,\,,\&,\;,\.]*)\"|","\\1&laquo;\\2&raquo;",$str);
И, кстати, тире тоже можно автоматом делать. Дело в том, что обычно тот дефис, который считается тире отделён от всего остального пробелами, т.е. так: " - ". Соответственно его можно заменять либо так: $str=str_replace(" - ","&nbsp;&mdash; ",$str); либо так: $str=str_replace(" - ","&nbsp;&#151; ",$str);
Перед тире должен стоять неразрывный пробел, т.к. тире не может отрываться от текста предшествующего ему.
 :::::  Гарин пишет 03.02.2004 @ 06:37 
Я не силен в программировании :(
но мне надо одну строчку подкорректировать, чтоб e-mail типа: bla.bla@bla.bla.ua не считала за неправильное написание

вот исходник:

$email_regular_expression="^([-!#\$%&'*+./0-9=?A-Z^_`a-z{|}~])+@([-!#\$%&'*+/0-9=?A-Z^_`a-z{|}~]+\\.)+[a-zA-Z]{2,6}\$";


будьте так добры, помогите

 :::::  _di пишет 21.02.2004 @ 14:37 
Гарин, такие емейлы реальны. такчто не морочь себе голову........
 :::::  _di пишет 21.02.2004 @ 14:37 
Гарин, такие емейлы реальны. такчто не морочь себе голову........
 :::::  Atomic Bombermen пишет 11.03.2004 @ 18:02 
Хочу предложить свой код для пролинковывания текста, который не коверкает тэги и обрабатывает URLы вида www.<>.<>, а не только начинающиеся с http://
Возможно он избыточен, но зато рабочий.

$nfulltext = eregi_replace("([\^\n| ])([[:alnum:]]+)://([^[:space:]]*)([[:alnum:]#?/&=])","\\1<a href=\"\\2://\\3\\4\">\\2://\\3\\4</a>",$nfulltext);

$nfulltext = eregi_replace ("[\^\n| ](www.[^[:space:]]*[[:alnum:]#?/&=])", " <A HREF=\"http://\\1\">\\1</A>", $nfulltext);
Имя:
Email:
URL

Введите сумму двух чисел девять и одинн (девять+одинн=?)
Запомнить мою информацию

* Html запрещен* Ваш E-mail опубликован не будет.

Copyright © 2000-2001 WebScript.Ru nas@webscript.ru
Design © 2001 by Parallax Design Studio (aka Spectator.ru)
Все торговые марки и авторские права на эту страницу принадлежат их соответствующим владельцам.
Сгенерировано за: 0.0214980