Как выполнить preg_split с использованием PREG_SPLIT_DELIM_CAPTURE

#php #regex

#php #регулярное выражение

Вопрос:

 $str = "blabla and, some more blah";
$delimiters = " ,¶.n";
$char_buff = preg_split("/(,) /", $str, -1, PREG_SPLIT_DELIM_CAPTURE);
print_r($char_buff);
  

Я получаю:

 Array ( 
  [0] => blabla and 
  [1] => , 
  [2] => some more blah 
)
  

Я смог выяснить, как использовать скобку, чтобы запятая отображалась в собственном элементе массива — но как я могу сделать это с несколькими разными разделителями (например, с разделителями в переменной $delimiters)?

Ответ №1:

Вам нужно создать символьный класс, перенеся разделители с помощью [ и ] .

 <?php
$str = "blabla and, some more blah. Blah.nSecond line.";
$delimiters = " ,¶.n";
$char_buff = preg_split('/([' . $delimiters . '])/', $str, -1,
             PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($char_buff);
  

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

Вывод

 Array
(
    [0] => blabla
    [1] =>  
    [2] => and
    [3] => ,
    [4] =>  
    [5] => some
    [6] =>  
    [7] => more
    [8] =>  
    [9] => blah
    [10] => .
    [11] =>  
    [12] => Blah
    [13] => .
    [14] => 

    [15] => Second
    [16] =>  
    [17] => line
    [18] => .
)
  

В зависимости от того, что вы делаете, использование strtok может быть более подходящим способом сделать это.

Комментарии:

1. Отлично — это работает. Есть ли хорошая ссылка на то, как изучать регулярные выражения, связанные с сопоставлением? Я несколько раз изучал, а затем забывал (базовое) регулярное выражение, потому что я недостаточно его использую. Я хотел бы выяснить, как я могу фиксировать некоторые разделители, но не другие.

2. @key2starz Вы создаете группу без захвата, начиная группу с (?: . Я всегда находил Regular-expression.info удобная ссылка. На их странице, посвященной группам и обратным ссылкам , содержится больше информации по этому вопросу.

3. Этот ответ вводит исследователей в заблуждение. m Модификатор шаблона здесь совершенно бесполезен. Здесь не задействованы якоря ( ^ и $ ), поэтому m это не приносит никакой пользы.

4. @mickmackusa Вы правы, я не уверен, о чем я думал, я, вероятно, просто увидел, что это n был один из разделителей, и предположил, что вам понадобится m . Я также не уверен, почему я не упомянул символьный класс вокруг разделителей. Я обновил ответ, спасибо.

5. В некоторых случаях (при передаче символов со специальными значениями в регулярное выражение) вам следует использовать preg_quote() при записи переменных в выражение (не тот случай в этом примере).

Ответ №2:

Используйте что-то вроде:

 '/([,.])/'
  

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

Ответ №3:

Каждое выражение-разделитель должно находиться внутри своей собственной группы.

 print_r(preg_split('/2d4/'      , '12345', null, PREG_SPLIT_DELIM_CAPTURE)); 
Array ( [0] => 1                            [1] => 5 )

print_r(preg_split('/(2)(d)(4)/', '12345', null, PREG_SPLIT_DELIM_CAPTURE)); 
Array ( [0] => 1 [1] => 2 [2] => 3 [3] => 4 [4] => 5 )