Поиск предложений между персонажами - PullRequest
0 голосов
/ 18 января 2020

Я пытаюсь найти предложения между трубой | и точкой ., например,

| Это один Это два.

Шаблон регулярного выражения, который я использую:

preg_match_all('/(:\s|\|+)(.*?)(\.|!|\?)/s', $file0, $matches);

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

Как я могу решить эту проблему?

РЕДАКТИРОВАТЬ: как это видно из регулярного выражения, я пытаюсь найти предложения МЕЖДУ (: или |) И (. Или! Или?)

Столбец или труба указывает начальную точку для фразы. Предложения могут быть:

: Sentence one. Sentence two. Sentence three. 
| Sentence one. Sentence two? 
| Sentence one. Sentence two! Sentence three?

Ответы [ 4 ]

1 голос
/ 18 января 2020

Это делает работу:

$str = '| This is one. This is two.';
preg_match_all('/(?:\s|\|)+(.*?)(?=[.!?])/', $str, $m);
print_r($m)

Вывод:

Array
(
    [0] => Array
        (
            [0] => | This is one
            [1] =>  This is two
        )

    [1] => Array
        (
            [0] => This is one
            [1] => This is two
        )

)

Демонстрация и объяснение

1 голос
/ 18 января 2020

Другим вариантом является использование \G для получения итеративных совпадений, утверждающих позицию в конце предыдущего совпадения и захвата значений в группе захвата, соответствующих точке и 0+ горизонтальных пробелов после.

(?:\|\h*|\G(?!^))([^.\r\n]+)\.\h*

По частям

  • (?: Группа без захвата
    • \|\h* Совпадение | и 0+ горизонтальных пробелов
    • | Или
    • \G(?!^) Подтвердить позицию в конце предыдущего матча
  • ) Закрыть группу
  • ( Группа захвата 1 - [^.\r\n]+ Совпадение 1+ раз с любым символом, кроме . или новой строкой
  • ) Закрыть группу
  • \.\h* Совпадение 1 . и 0+ горизонтальных пробелов

Regex demo | Php демо

Например

$re = '/(?:\|\h*|\G(?!^))([^.\r\n]+)\.\h*/';
$str = '| This is one. This is two.
John loves Mary.| This is one. This is two.';

preg_match_all($re, $str, $matches, PREG_SET_ORDER, 0);
print_r($matches);

Выход

Array
(
    [0] => Array
        (
            [0] => | This is one. 
            [1] => This is one
        )

    [1] => Array
        (
            [0] => This is two
            [1] => This is tw
        )

)
1 голос
/ 18 января 2020

Я бы оставил это простым и просто соответствовал:

\s*[^.|]+\s*

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

$input = "| This is one. This is two.";
preg_match_all('/\s*[^.|]+\s*/s', $input, $matches);
print_r($matches[0]);

Это печатает:

Array
(
    [0] =>  This is one
    [1] =>  This is two
)
0 голосов
/ 18 января 2020

Для простоты найдите все между | и ., а затем разделите:

$input = "John loves Mary. | This is one. This is two. | Sentence 1. Sentence 2.";
preg_match_all('/\|\s*([^|]+)\./', $input, $matches);
if ($matches) {
    foreach($matches[1] as $match) {
        print_r(preg_split('/\.\s*/', $match));
    }
}

Отпечатки:

Array
(
    [0] => This is one
    [1] => This is two
)
Array
(
    [0] => Sentence 1
    [1] => Sentence 2
)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...