Как включить разделитель разделения в результаты для preg_split()?

У меня есть этот простой шаблон, который разбивает текст на периоды:

$text = preg_split("/[\.:!\?]+/", $text);

Но я хочу включить . : или ! в конец элементов массива.

То есть теперь для "хорошо:новости.всем!" У меня есть:

array("good", "news", "everyone", "");

Но я хочу:

array("good:", "news.", "everyone!", "");

person skyline26    schedule 01.08.2012    source источник


Ответы (2)


Ну вот:

preg_split('/([^.:!?]+[.:!?]+)/', 'good:news.everyone!', -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);

Как это работает: шаблон фактически превращает все в разделитель. Затем, чтобы включить эти разделители в массив, вы можете использовать константу PREG_SPLIT_DELIM_CAPTURE. Это вернет массив, например:

array (
    0 => '',
    1 => 'good:',
    2 => '',
    3 => 'news.',
    4 => '',
    5 => 'everyone!',
    6 => '',
);

Чтобы избавиться от пустых значений, используйте PREG_SPLIT_NO_EMPTY. Чтобы объединить две или более из этих констант, мы используем побитовый оператор |. Результат:

array (
    0 => 'good:',
    1 => 'news.',
    2 => 'everyone!'
);
person Elias Van Ootegem    schedule 01.08.2012
comment
А что, если мне нужно разделить слово good: как целое с помощью : ? И могу ли я также добавить теги ‹strong›? Так что мне нужно ‹strong›Хорошо:‹/strong› - person user1551496; 05.03.2016
comment
@ user1551496: Тогда вы имеете дело с разметкой. Используйте синтаксический анализатор вместо регулярного выражения, поскольку регулярное выражение плохо обрабатывает разметку - person Elias Van Ootegem; 05.03.2016
comment
@NinoŠkopac: [^.:!?]+ жадно соответствует всем символам, кроме .:!?, один или несколько раз, следующая группа символов жадно соответствует .:!? один или несколько раз. Эти два класса символов сгруппированы, потому что шаблон заключает их в (), поэтому в результате вы сопоставляете все. Однако совпадение заканчивается всякий раз, когда встречается одно или несколько из .:!?, а следующее совпадение откладывается в новой группе, поэтому массив -> match, empty, match, empty... используя PREG_SPLIT_DELIM_CAPTURE, вы гарантируете, что совпадения используются как разделитель находится в массиве, PREG_SPLIT_NO_EMPTY избавляется от пустых битов - person Elias Van Ootegem; 02.08.2017
comment
По сути, каждая часть строки является разделителем, и вы разбиваете пустые строки. Вы игнорируете пустые строки и просите preg_split дать вам совпадающие разделители, что и было после OP - person Elias Van Ootegem; 02.08.2017

Не используйте PREG_SPLIT_DELIM_CAPTURE, если вы используете положительный просмотр назад в своем шаблоне. Функция сохранит разделители.

$text = preg_split('/(?<=[.:!?])/', 'good:news.everyone!', 0, PREG_SPLIT_NO_EMPTY);

Если вы используете lookbehind, он просто будет искать символ, не сопоставляя его. Итак, в случае preg_split() функция не будет отбрасывать символ.

Результат без флага PREG_SPLIT_NO_EMPTY:

array (
    0 => 'good:',
    1 => 'news.',
    2 => 'everyone!',
    3 => ''
);

Результат с флагом PREG_SPLIT_NO_EMPTY:

array (
    0 => 'good:',
    1 => 'news.',
    2 => 'everyone!'
);

Вы можете протестировать его с помощью интернет-тестера функций PHP.

person pmrotule    schedule 05.07.2016
comment
вы также можете использовать положительный просмотр вперед с ?= вместо ?‹=, чтобы разделитель всегда заканчивался в следующем совпадении «хорошо», ': новости', 'все!' - person Jonathan dos Santos; 10.05.2020