RegEx для разбора "Диагностического кода" в отклоненном письме

Я пытаюсь читать отклоненные электронные письма, подключаясь через PHP к учетной записи IMAP и получая все электронные письма. Я ищу, чтобы получить сообщение "Диагностический код" для каждого электронного письма, и я написал следующее регулярное выражение:

/Diagnostic-Code:\s+?(.*)/i

Сообщение, которое я пытаюсь разобрать, таково:

Diagnostic-Code: smtp; 550-5.1.1 The email account that you tried to reach does
    not exist. Please try 550-5.1.1 double-checking the recipient's email
    address for typos or 550-5.1.1 unnecessary spaces. Learn more at 550 5.1.1
    https://support.google.com/mail/?p=NoSuchUser 63si4621095ybi.465 - gsmtp

Регулярное выражение работает частично, означая, что оно выбирает только первую строку текста. Я хочу иметь возможность получить все сообщение, так что все четыре строки текста.

Можно ли обновить выражение, чтобы сделать это сопоставление?

Благодарю.

3 ответа

Решение
/Diagnostic-Code:\s(.*\n(?:(?!--).*\n)*)/i
  • результат будет в группе захвата 1
  • первый .*\n соответствует первой строке, включая завершающий перевод строки
  • (?:(?!--).*\n)* соответствует повторяющимся строкам, которые не начинаются "-"

Если может быть несколько сообщений, начинающихся с Diagnostic-Code: Вы можете использовать:

^Diagnostic-Code:\K.*(?:\R(?!Diagnostic-Code:).*)*

Смотрите демо-версию регулярного выражения | Php демо

объяснение

  • ^ Начало строки
  • Diagnostic-Code: Подходим буквально
  • \K.* Забудьте, что было найдено, и следуйте остальной части строки
  • (?: Не каптуриновая группа
    • \R(?!Diagnostic-Code:).* Совпадение последовательности новой строки в юникоде с последующим отрицательным заглядыванием, чтобы проверить !Diagnostic-Code:, Если это так, то сопоставьте всю строку
  • )* Закройте группу без захвата и повторите 0+ раз

Добавить s флаг:

/Diagnostic-Code:\s+?(.*)/si

Из этого вопроса:

В PHP... [t] он в конце заставляет точку соответствовать всем символам, включая символы новой строки.

Это позволит вашему регулярному выражению соответствовать целиком (см. Это регулярное выражение101). Просто не забудьте добавить какой-нибудь способ закончить это, если у вас есть больше текста после этого.

Другие вопросы по тегам