PHP имеет функцию preg_split
для такого рода вещей. preg_split
позволяет разбить строку по разделителю, который вы можете определить как шаблон регулярного выражения. Кроме того, он имеет аргумент, который позволяет вам включать совпавший разделитель в результаты сопоставления / разделения.
Таким образом, вместо написания регулярного выражения, соответствующего полному тексту, регулярное выражение предназначено для самого разделителя.
Пример:
$string = "This is a t3xt with special characters like !#. *AND and this is another text with special characters *AND this repeats *OR do not repeat *OR have more strings *AND finish with this string.";
$string = preg_split('~(\*(?:AND|OR))~',$string,0,PREG_SPLIT_DELIM_CAPTURE);
print_r($string);
Выход:
Array
(
[0] => This is a t3xt with special characters like !#.
[1] => *AND
[2] => and this is another text with special characters
[3] => *AND
[4] => this repeats
[5] => *OR
[6] => do not repeat
[7] => *OR
[8] => have more strings
[9] => *AND
[10] => finish with this string.
)
Но если вы действительно хотите придерживаться preg_match
, вам вместо этого нужно будет использовать preg_match_all
, что аналогично preg_match
(что вы отметили в своем вопросе), за исключением того, что это делает глобальные / повторные совпадения.
Пример:
$string = "This is a t3xt with special characters like !#. *AND and this is another text with special characters *AND this repeats *OR do not repeat *OR have more strings *AND finish with this string.";
preg_match_all('~(?:(?:(?!\*(?:AND|OR)).)+)|(?:\*(?:AND|OR))~',$string,$matches);
print_r($matches);
Выход:
Array
(
[0] => Array
(
[0] => This is a t3xt with special characters like !#.
[1] => *AND
[2] => and this is another text with special characters
[3] => *AND
[4] => this repeats
[5] => *OR
[6] => do not repeat
[7] => *OR
[8] => have more strings
[9] => *AND
[10] => finish with this string.
)
)
Во-первых, обратите внимание, что в отличие от preg_split
, preg_match_all
(и preg_match
) возвращают массив с множественным затемнением, а не одноцветный. Во-вторых, технически шаблон, который я использовал, можно немного упростить, но это будет стоить того, чтобы ссылаться на несколько массивов в возвращаемом множественном массиве (один массив для сопоставленного текста, а другой массив для сопоставленных разделителей) , что вам затем придется пройти через и альтернативную ссылку; IOW будет дополнительная очистка для получения окончательного единственного массива с обоими наборами совпадений, как указано выше.
Я показываю этот метод только потому, что вы технически задали его в своем вопросе, но я рекомендую использовать preg_split
, так как он устраняет большую часть этих накладных расходов и почему он был создан в первую очередь (для лучшего решения сценариев как это).