Кавычки и regular expressions
Поначитался я на разных сайтах про кавычки. Вот тут, например, или вот тут. Дескать, кавычки нужны только вот такие - « и вот такие - », а никак не такие - '', и все остальное - от лукавого!
Сел, стал думу думать, как бы так сделать, чтобы в тексте кавычки вот такие - '' сами (с помощью маленького 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»:
,"«1»", $contents);
Для еще лучшей работы в конце стоит добавить еще и $contents = str_replace ("«","«", $contents);. Можно, конечно, делать это в первых трех строчках, но у меня тогда ereg_replace работал дольше и глючил...
Итого:
$contents = str_replace (" ""," «", $contents);
$contents = str_replace ("n""," «", $contents);
$contents = str_replace (">"",">«", $contents);
$contents = ereg_replace ('«([^"]*)"',"«1»", $contents);
$contents = str_replace ("«","«", $contents);
Коротко и ясно...
... ну ладно, просто «коротко»...
Как и полагается - known bugs. Известные ошибки. Если на вашем сайте размещаются примеры скриптов, (как у меня, например) то могут быть проблемы в том случае, если где-то в теле скрипта после пробела стоит кавычка. Решение - перед кавычкой. Либо думайте сами. (С 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);
Вот и все.
|