регулярка от висячих предлогов

KK
На сайте с 25.07.2006
Offline
138
3917

Помогите составить правильную регулярку для борьбы с висячими предлогами. Нашел тему для ворда - http://blog.alexkrylov.ru/journalshowcomments.php?jpostid=116707137&journalid=1865558&go=next&categ=0

По этому принципу код выходит таким:

$result = preg_replace("/([ | ])([а-яА-Яa-zA-Z]{1,2}) ([а-яА-Яa-zA-Z])/",

"\\1\\2 \\3",

$text);

$result = preg_replace("/([ | ])([а-яА-Яa-zA-Z]{1,2}) ([а-яА-Яa-zA-Z])/",

"\\1\\2 \\3",

$result);

Нужно дублировать два раза, иначе не все заменяет. Может можно более разумно ее составить? Не силен в регулярках.

P.S. Висячий предлог (ВП) — это тот, что оставлен в конце строки. По правилам верстки не допускается. Т.е. после каждого предлога и союза необходимо ставить неразрывный пробел. Хз зачем так издеваться, но надо блин.

siv1987
На сайте с 02.04.2009
Offline
427
#1

Kel_Kimpbell, дайте примеров "висячих предлогов", а то чота не хочется на ночь глядя мозг напрягать)

C
На сайте с 04.02.2005
Offline
277
#2
По правилам верстки не допускается.

По правилам типографики

Вот http://rmcreative.ru/blog/post/tipograf есть нужный Вам класс

---------- Добавлено 15.01.2013 в 00:23 ----------

siv1987:
Kel_Kimpbell, дайте примеров "висячих предлогов", а то чота не хочется на ночь глядя мозг напрягать)

Вот смотрите.. подошел к чему-то

С точки зрения типографики к - это висячий предлог, он должен перенестись вместе с ближ словом

т.е

подошел

к чему-то

Но не

подошел к

чему-то

Чтобы не перенесся, нужно поставить неразрывный пробел  

---------- Добавлено 15.01.2013 в 00:32 ----------

выдраная из примера регулярка

$prepos = '(:?а|без|безо|в|во|вне|да|для|до|ее|ещё|еще|и|или|из|изо|или|их|за|к|как|ко|меж|между|на|над|надо|не|ни|но|о|об|обо|от|ото|перед|передо|по|под|подо|пред|предо|при|про|около|с|сквозь|со|то|там|у|уж|что|через|я|'.$sym['mdash'].')';

'/(?<=\s|^|\W)'.$prepos.'(\s+)/i' => '$1'.$sym['nbsp'],

siv1987
На сайте с 02.04.2009
Offline
427
#3


'/([ ]|&nbsp;)([а-яa-z]{1,2}) ([а-яa-z])/i', '\\1\\2&nbsp;\\3', $text

если есть проблемы с повторяющимся пробелами (два и более) [ ] заменить на [ ]+

KK
На сайте с 25.07.2006
Offline
138
#4

Огромное спасибо!

VHS-1980
На сайте с 21.05.2010
Offline
91
#5

Понимаю, что у каждого свой велосипед, но мне понравилось данное решение:

http://www.webfilin.ru/instruments/typograf

ну и такое простое решение, свободно лежащее в сети:

<?php
function typograph($text) {
$text = html_entity_decode($text, ENT_QUOTES, 'utf-8');
$arr = array(
// Убираем символ троеточия
'/…/u' => '...',
// Кавычки «ёлочки» &laquo; &raquo;
'/(^|[\s;\(\[-])"/' => '$1«',
'/"([\s-\.!,:;\?\)\]\n\r]|$)/' => '»$1',
'/([^\s])"([^\s])/' => '$1»$2',
// Длинное тире &mdash;
'/(^|\n|["„«])--?(\s)/u' => '$1—$2',
'/(\s)--?(\s)/' => ' —$2',
// Непереносимый проблел после коротких слов &nbsp;
'/([\s][a-zа-яё]{1,2})[ ]/iu' => '$1 '
);
foreach ($arr as $key=>$val) {
$text = preg_replace($key, $val, $text);
}
// Вложенные кавычки &bdquo; &ldquo;
while (preg_match('/(«[^«»]*)«/mu', $text)) {
$text = preg_replace('/(«[^«»]*)«/mu', '$1„', $text);
$text = preg_replace('/(„[^„“«»]*)»/mu', '$1“', $text);
}
return $text;
}
gormarket
На сайте с 29.12.2010
Offline
47
#6

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

Например такое предложение: "Он и сам мог справиться, но и от помощи не стал отказываться."

Если приведенная ТС регулярка уже использовала какие-то символвы строки в найденной подстроке, они уже не будут использоваться для дальнейшего поиска.

Поэтому после первого прохода по строке получается вот так

"Он и&nbsp;сам мог справиться, но&nbsp;и от&nbsp;помощи не&nbsp;стал отказываться."

И чтоб заменить оставшийся пробел, приходится применять замену еще раз

Ни один из предложенных примеров не решает этой проблем за один раз.

Все они способны сделать полную замену только после двух применений.

Но решение есть, например такое:


$result = preg_replace("/(?<=&nbsp;| )([а-яА-Яa-zA-Z]{1,2}) (?=[а-яА-Яa-zA-Z])/", "\\1&nbsp;", $text);

В результате после однократного применения получается такая строка

"Он и&nbsp;сам мог справиться, но&nbsp;и&nbsp;от&nbsp;помощи не&nbsp;стал отказываться."

Эта регулярка включает в найденное только "предлог" и пробел после него, но одновременно (не включая в найденное) проверяя наличие пробельного символа перед "предлогом" и текстовый символ после пробела за "предлогом".

Товары и цены в магазинах Вашего города: Городской рынок (http://gormarket.ru/)
KK
На сайте с 25.07.2006
Offline
138
#7

А не подскажете еще как типограф в битрикс встроить? Вот этот http://rmcreative.ru/blog/post/tipograf

Т.е. хочется обработать сразу весь контент, а не каждую переменную выискивать в шаблонах.

Я так понимаю это нужно делать через буфер. Но пока не нашел где именно идет обработка буфера.

VHS-1980
На сайте с 21.05.2010
Offline
91
#8

Вы все верно понимаете - нужно обрабатывать буфер. Но гораздо более правильным решением было бы обрабатывать отдельные участки кода, т.к. не всегда полный буфер содержит данные, необходимые для типографирования - коды js, навигация и т.п.

С битриксом не знаком, поэтому подсказать точно не смогу.

богоносец
На сайте с 30.01.2007
Offline
753
#9
gormarket:
но&nbsp;и&nbsp;от&nbsp;помощи

А вот несколько более часто встречающиеся последовательности лучше так жестоко не обрабатывать. Например «не» привязывается всегда, а в «и не» — и не&nbsp;

Мне казалось это лучше делать по списку, его приходится делать, часто в текстах криво употребляется «т.е.» — т.&nbsp;е.&nbsp;

то&nbsp;есть

Некоторые тексты кишат архаикой: ибо&nbsp;жизнь твоя...

или неформальным употреблением дефисов: не-поклонник — не& #8209;поклонник

«из-за» — из& #8209;за&nbsp;

...

&nbsp;ли

...

кое-что

кое& #8209;что

Ещё можно вспомнить

инициалы А.С.Пушкин — А.&nbsp;С.&nbsp;Пушкин

забытые пробелы —так.

лишние пробелы: слово ,

И кто ещё возьмётся добавить к этому всему висячую пунктуацию, чтобы за один проход всё правильно получалось?

C
На сайте с 04.02.2005
Offline
277
#10
богоносец:
И кто ещё возьмётся добавить к этому всему висячую пунктуацию, чтобы за один проход всё правильно получалось?

Все описанное и за один проход?

А смысл?

Вот регулярка для правильных Инициалов

'~([А-ЯA-Z]\.)\s?([А-ЯA-Z]\.)\s?([А-Яа-яA-Za-z]+)~s'

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