Борьба с кавычками (с php)

spectator.ru представляет заметку, борющуюся за звание самой скучной заметки года.

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

Сел, стал думу думать, как бы так сделать, чтобы в тексте кавычки вот такие – '' сами (с помощью маленького 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-ем и примерами из него проблем нет).

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

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

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

ps/ в качестве примера я вставил пока эти строчки в мой движок, посмотрите, какие во всех заметках стали кавычки.

p.p.s/ Немного поколдовал. Этот вариант лишен двух багов – когда внутри кавычек содержатся тэги и бага с кавычками внути кавычек.

$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% медленней. У кого есть добавления – присылайте.

p.p.p.s. Кстати, там же написано:

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

Замену «неправильных» тире на правильные можно сделать совсем просто – «правильные» тире – это те, которые с двух сторон окружены пробелы. Их и меняем на «Em Dash».

Автор: Дмитрий Смирнов
Информация взята с сайта Spectator


© журнал принадлежит Web Creation
по всем вопросам обращаться А. Кузьмин