Заставить preg_match_all прекратить захват новой строки?

1

Рассмотрим этот пример, где я пытаюсь получить "сырые" адреса электронной почты:

<?php
$tststr = 'To: [email protected]
To: [email protected], [email protected]
To: User <[email protected]>
To: User <[email protected]>, Another User <[email protected]>
';

//~ preg_match('/([^ <]*@[^ >,]*)/', $tststr, $matches); // no /g
preg_match_all('/([^ <]*@[^ >,$]*)/m', $tststr, $matches);

foreach ($matches as $key=>$val) {
  //~ print("val [".$key."] = ". $val . "\n");
  foreach ($val as $key1=>$val1) {
    print("val [".$key."][".$key1."] = ". $val1 . "\n");
  }
}

print "'".$matches[0][0]."'\n";
?>

Я думаю, что регулярное выражение работает следующим образом:

И в основном это работает, в результате:

val [0][0] = [email protected]
To:
val [0][1] = [email protected]
val [0][2] = [email protected]
To:
val [0][3] = [email protected]
val [0][4] = [email protected]
val [0][5] = [email protected]
val [1][0] = [email protected]
To:
val [1][1] = [email protected]
val [1][2] = [email protected]
To:
val [1][3] = [email protected]
val [1][4] = [email protected]
val [1][5] = [email protected]
'[email protected]
To:'

... кроме того, как вы можете видеть, совпадение [0] [0] действительно содержит новую строку, а " To: - из следующей строки!

Итак, как я могу сделать preg_match_all остановки в конце строки?

Subquestion: почему у меня есть идентичный набор результатов в $matches[0] matches $matches[0] и $matches[1]? Могу ли я игнорировать $matches[1] и просто обрабатывать $matches[0]?

Теги:

1 ответ

2
Лучший ответ

Просто замените пространство внутри класса символов на \s. Следовательно, это не будет соответствовать пробелу, включая разрывы строк.

preg_match_all('/([^\s<]*@[^\s>,$]*)/m', $tststr, $matches);

Это может быть дополнительно упрощено, как показано ниже, т.е. Вам не нужно использовать группу захвата и многострочный модификатор m

preg_match_all('/[^\s<]*@[^\s>,$]*/', $tststr, $matches);

DEMO

$ внутри класса char будет соответствовать буквальному символу $. Нет, это не похоже на конец линии. Нам не нужно включать \n внутри отрицаемого класса char, так как \s выполняет задание.

preg_match_all('/[^\s<]*@[^\s>,]*/', $tststr, $matches);
  • 0
    Большое спасибо за это @AvinashRaj - это работает; и удаление скобок группы захвата также удаляет набор $matches[1] . Я также думаю, что $ в [^\s>,$]* больше не нужен, так как я думал, что это будет символ для соответствия новой строке. Еще раз спасибо - ура!
  • 1
    Вы не имеете в виду буквальный $ ? затем удалите его из класса персонажей. $ внутри класса char потеряет свое значение (соответствующий конец границы строки)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню