разделить на preg_split

Этот вопрос очень похож на использовать preg_split вместо split, но у меня есть некоторые путаницы с регулярным выражением, которые я хотел бы прояснить.

Пытаюсь обновить некоторые существующие функции split(), чтобы вместо них использовать preg_split(), и получаю неясные результаты. Выполнение приведенного ниже кода даст мне массивы разной длины, и я не знаю, почему.

Из того, что я вижу, раскол заранее соответствует \n с возможным \r. И я думаю, что preg_split делает то же самое, но тогда почему он создает 2 разделения? Это связано с ленивым/жадным сопоставлением?

Демонстрационный код:

$test = "\r\n";

$val = split('\r?\n', $test); //literal interpretation of string
$val_new = split("\r?\n", $test); //php understanding that these are EOL chars
$val2 = preg_split('/\r?\n/', $test);

var_dump($val); // returns array(1) { [0]=> string(2) " " }
var_dump($val2); // returns array(2) { [0]=> string(0) "" [1]=> string(0) "" }

Изменить: добавлено в $val_new на основе комментариев Kolinks, потому что они помогли прояснить мое понимание проблемы, поэтому могут быть полезны и другим.


person Doug McK    schedule 23.04.2012    source источник


Ответы (2)


split не воспринимает \r и \n как специальные символы, а поскольку вы использовали одинарные кавычки, PHP также не рассматривает их как специальные символы. Итак, split ищет буквальное \\n или \r\n.

preg_split, с другой стороны, понимает \r и \n как специальные символы, поэтому, несмотря на то, что PHP не обрабатывает их так, как это делает PCRE, и поэтому строка разбивается правильно.

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

person Niet the Dark Absol    schedule 23.04.2012
comment
Ага, теперь это имеет смысл и помогло мне решить мою проблему. Большое спасибо за четкое объяснение - отмечу это как ответ, как только мне будет позволено - person Doug McK; 23.04.2012

Вы должны PREG_SPLIT_NO_EMPTY пометить как 3-й аргумент preg_split, чтобы игнорировать пустые токены в разделенном массиве. Итак, если вы используете

preg_split('/\r?\n/', $test, PREG_SPLIT_NO_EMPTY);

тогда он будет вести себя так же, как функция разделения.

И, кстати, ваше использование \r?\n в функции разделения не выполняет никакого разделения (поскольку разделение не понимает \r и \n в одинарных кавычках) и возвращает вашу исходную строку обратно.

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

split("\r?\n", $test);

чтобы разделить вашу строку на массив из 2 элементов.

person anubhava    schedule 23.04.2012
comment
Это было в середине некоторых правок, пожалуйста, проверьте это сейчас для лучшего объяснения. - person anubhava; 23.04.2012
comment
Все еще неправильно, тем более что split() специально определен как Разделить строку на массив регулярным выражением< /я> - person Niet the Dark Absol; 23.04.2012
comment
Ах да, вы правы, сейчас вносим исправления. Спасибо, что указали на это. - person anubhava; 23.04.2012
comment
Спасибо, это действительно делает его одинаковым и заставило меня прочитать об этом - person Doug McK; 23.04.2012