preg_split, как включить разделительный разделитель в результаты?

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

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

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

IE теперь для «хорошего: news.все!» у меня есть:

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

но я хочу:

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

Ну вот:

 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!' ); 

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

 $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 Online Function Tester .