PHP Regex: как совместить \r и\n, не используя [\ r\n]?

Я тестировал \v (вертикальное пустое пространство) для соответствия \r\n и их комбинаций, но я обнаружил, что \v не соответствует \r и \n. Ниже мой код, который я использую.

$string = "
Test
";

if (preg_match("#\v+#", $string )) {
  echo "Matched";
} else {
  echo "Not Matched";
}

Чтобы быть более ясным, мой вопрос в том, есть ли другая альтернатива для соответствия \r\n?

Ответ 1

PCRE и новые строки

PCRE имеет избыток связанных с новой строкой escape-последовательностей и альтернатив.

Ну, отличная escape-последовательность, которую вы можете использовать здесь, \R. По умолчанию \R будет соответствовать последовательности строк Unicode, но его можно настроить с использованием разных альтернатив.

Чтобы соответствовать любой последовательности строк Unicode, которая находится в диапазоне ASCII.

preg_match('~\R~', $string);

Это эквивалентно следующей группе:

(?>\r\n|\n|\r|\f|\x0b|\x85)

Чтобы соответствовать любой последовательности строк Unicode; включая символы новой строки вне диапазона ASCII и как разделитель строк (U+2028), так и разделитель абзацев (U+2029), вы хотите включить флаг u (unicode).

preg_match('~\R~u', $string);

Модификатор u (unicode) включает дополнительную функциональность PCRE, а строки Pattern обрабатываются как (UTF-8).

Это эквивалентно следующей группе:

(?>\r\n|\n|\r|\f|\x0b|\x85|\x{2028}|\x{2029})

Можно ограничить \R только CR, LF или CRLF:

preg_match('~(*BSR_ANYCRLF)\R~', $string);

Это эквивалентно следующей группе:

(?>\r\n|\n|\r)

Дополнительные

Поддерживаются пять различных соглашений для указания разрывов строк в строках:

(*CR)        carriage return
(*LF)        linefeed
(*CRLF)      carriage return, followed by linefeed
(*ANYCRLF)   any of the three above
(*ANY)       all Unicode newline sequences

Примечание: \R не имеет специального значения внутри класса символов. Как и другие непризнанные escape-последовательности, он по умолчанию считается буквальным символом "R".

Ответ 2

Это не отвечает на вопрос об альтернативах, потому что \v отлично работает

\v соответствует любому символу, который считается вертикальным пробелом; это включает в себя символы возврата каретки и строки строки (новая строка) плюс несколько других символов, все из которых перечислены в таблице ниже.

Вам нужно только изменить "#\v+#" на

  • "#\\v+#" удалить обратную косую черту

или

  • '#\v+#' использовать одинарные кавычки

В обоих случаях вы получите соответствие для любой комбинации \r и \n.

Update:

Чтобы сделать область \v прозрачной по сравнению с \r, из perlrebackslash

  • \R
    \r соответствует общей строке новой строки; то есть все, что считается последовательностью строк в Unicode. Сюда входят все символы, сопоставляемые \v (вертикальные пробелы),...

Ответ 3

Если есть какое-то странное требование, которое мешает вам использовать литерал [\r\n] в вашем шаблоне, вы всегда можете использовать шестнадцатеричные escape-последовательности:

preg_match('#[\xD\xA]+#', $string)

Этот шаблон эквивалентен [\r\n]+.

Ответ 4

Чтобы сопоставить каждую LINE данной строки, просто используйте ^$ Якоря и советьте свой механизм регулярных выражений работать в многострочном режиме. Тогда ^$ будет соответствовать началу и концу каждой строки, а не целым целым начало и конец.

http://php.net/manual/en/reference.pcre.pattern.modifiers.php

в PHP, это будет модификатор m после шаблона. /^(.*?)$/m будет просто соответствовать каждой строке, разделенной любым вертикальным пространством внутри данной строки.

Btw: для разделения строк вы также можете использовать константу split() и константу PHP_EOL:

$lines = explode(PHP_EOL, $string);

Ответ 5

Проблема заключается в том, что вам нужно использовать многострочный вариант или опцию dotall при использовании точки. Он идет в конце разделителя.

http://www.php.net/manual/en/regexp.reference.internal-options.php

$string = "
Test
";
if(preg_match("#\v+#m", $string ))
echo "Matched";
else
echo "Not Matched";

Ответ 6

Чтобы сопоставить новую строку в PHP, используйте константу php PHP_EOL. Это межплатформенная платформа.

if (preg_match('/\v+' . PHP_EOL ."/", $text, $matches ))
   print_R($matches );

Ответ 7

Это регулярное выражение также соответствует символам новой строки \n и символа возврата каретки \r.

(?![ \t\f])\s

DEMO

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

(?:(?![ \t\f])\s)+

DEMO