[ Поиск ] - [ Пользователи ] - [ Календарь ]
Полная Версия: Подскажите на счёт регулярки
Retox
Хочу получить из текста предложения, использую.
$pattern = "|[А-Я](.*?)[.!?]|si";


Но на ряду со стандартными предложениями - которые начинаются с заглавной и заканчиваются .?!. Регулярка тянет и такие, начинающиеся с дефиса.
Ex.
— Хм… — Он будет очень послушный кот.

Что нужно подкорректировать, что бы выдавались только предложения где первая буква заглавная.
Всем заранее благодарен :)
Zzepish
вот:
'#(?<=[!?\.])(?=[\s-—]+[А-ЯЁ])#us'
Retox
Спасибо smile.gif проблема была в том что текстовой файл был в кодировке windows-1251 а скрипт UTF-8...
Zzepish
Retox
Утебя разве учитывает дефис?
Мой паттерн пихать в preg_split
OleKh
Цитата (Zzepish @ 22.04.2014 - 10:23)
Мой паттерн пихать в preg_split


Меня очень заинтриговал этот паттерн. Не мог бы мне как рыбак рыбаку пояснить как это должно работать.
Zzepish
OleKh
Все простор.
Паттерн смотрит назад, если видит перечень символов (?!.) которые обозначают конец строки. Далее он смотрит в перед, и проверяет строку на символы, обозначающие начало строки, где после признаков окончания строки есть тире, пробел, перенос за которым идёт слово с большой буквы. Если нет большой буквы, то считает, что это текущее предложение. При этом паттерн ничего не вырезает, так как использует систему посмотреть назад и вперёд, которая предусматривает только просмотр, но не удаление символов, как при стандартном разрезании строки.
Надеюсь понятно. Ибо я не очень хорошо объясняют вещи, которые имеют запутанную систему)
OleKh
Zzepish
+1

Понятно, но не совсем. В мануале.

Цитата
Возвращает массив, состоящий из подстрок заданной строки subject, которая разбита по границам, соответствующим шаблону pattern.


Цитата (Zzepish @ 22.04.2014 - 12:37)
Если нет большой буквы, то считает, что это текущее предложение.


Т.е. паттерн должен определять границу. Одну границу, в данном случае (., !, ?) и разделять строку. Или две границы? Начала и окончания строки? Если две границы тогда очень странно как такой паттерн определяет и зачем ему знаять начало строки, когда разделяет по символу конца строки.
Zzepish
OleKh
Разделяет он по пустому месту(меж символьному пространству) которое соответсвует данному паттерну
OleKh
Ок.

Пример. Случайный анекдот выбрал.

$str ='Сидят мама-моль и ее маленький сын в шкафу и едят шубу. Сын спрашивает:
- Мама! Можно я полетаю?
- Нет! Лучше ешь шубу!
- Жалко! А я вчера летал, мне так аплодировали!
'
;

$res = preg_split('#(?<=[!?\.])(?=[\s-—]+[А-Я])#isu', $str);

echo "<pre>".print_r($res, 1)."</pre>";


А теперь чуть изменим содержание

$str ='Сидят мама-моль и ее маленький сын в шкафу и едят шубу. Сын спрашивает:
тест - Мама! Можно я полетаю?
тест тест тест
- Нет! Лучше ешь шубу!
- Жалко! А я вчера летал, мне так аплодировали!
'
;


и результат не получается, хотя по идее

Цитата
- Нет! Лучше ешь шубу!


должно быть выделено, т.к. положительная опережающая проверка вперед/назад должна выделить эту часть текста, правильно?
Zzepish
OleKh
а ты мне покажи хоть один текст, который так будет написан!

Кстати! Если ты первый Тест напишешь с большой буквы! так что все гуд.
Все работает как задуманно)
OleKh
Цитата (Zzepish @ 22.04.2014 - 12:37)
Все простор.Паттерн смотрит назад, если видит перечень символов (?!.)

Не всё так просто, хотя и не слишком сложно когда уже кажется думаешь что разобрался :)

Ошибка заключается в том, что

- изначально использование preg_split было не в тему, т.к. функция предназначена для разделения, а не для поиска по шаблону,
-любая комбинация левой и правой части выражения выдаст результат
(в примере выше слева возвращает ?, а справа "т", т.к. модификатор i получается "Т" и наличие "-" необязательно)
-
Пример проще

$str= 'A test string!- The test string?- The new test string!The test string?aaaa- The new test stringThe other strings.';

$res = preg_split('#(?<=\?|\!|\.)(?=\-)#', $str);

echo "<pre>".print_r($res, 1)."</pre>";


Array
(
[
0] => A test string!
[
1] => - The test string?
[
2] => - The new test string!The test string?aaaa- The new test stringThe other strings.
)


Из которого можно сделать вывод, что данное регулярное выражение может разделить строку по разделителям (
1. ?-
2. !-
3. .-
)

при этом сами разделители остаются в чем тоже очень много пользы.
Zzepish
OleKh
У тебя не разбивает строку: Привет! Как дела?

Твоя регулярка прокололась:
user posted image


а split или match не имеет в данном контексте никакого значения. Мне удобней было через split
OleKh
Цитата (Zzepish @ 22.04.2014 - 20:14)
Твоя регулярка прокололась:

не суть важно, моЯ регулярка не в теме

Цитата (Zzepish @ 22.04.2014 - 20:14)
а split или match не имеет в данном контексте никакого значения. Мне удобней было через split

А вот тут очень даже имеет. То, что там выше было написано о "межсимвольном пространстве" и "пустых местах" между символами - вообще не понятно что значит, это ж не CSS. В строке из символов, например abc, есть только 3 символа a, b и c. И этот пример как раз очень наглядно показывает отличие preg_match от preg_split

$str='abc';

preg_match('##', $str, $match);
echo "<pre>".print_r( $match, 1)."</pre>";


$res = preg_split('##', $str, -1, PREG_SPLIT_NO_EMPTY);
echo "<pre>".print_r($res, 1)."</pre>";

Array
(
[
0] =>
)

Array
(
[
0] => a
[1] => b
[2] => c
)


Zzepish
OleKh
но у меня же все работает, как надо?)))
Быстрый ответ:

 Графические смайлики |  Показывать подпись
Здесь расположена полная версия этой страницы.
Invision Power Board © 2001-2024 Invision Power Services, Inc.