шаблон preg_match для поиска содержимого строки между тегами <html>и </html> - PullRequest
3 голосов
/ 03 сентября 2010

Я работаю над сценарием PHP, который читает содержимое электронных писем и извлекает определенную информацию для хранения в базе данных.

Используя imap_fetchbody ($ imap_stream, $ msg_number, 1), явозможность получить в теле письма.В некоторых случаях (особенно электронная почта, отправляемая в виде SMS-сообщения с мобильных телефонов), тело письма выглядит так:

===------=_Part_110734_170079945.1283532109852
Content-Type: text/html;charset=UTF-8;
Content-Transfer-Encoding: 7bit
Content-Disposition: inline

<html> 
    <head> 
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> 
        <title>Multimedia Message</title> 
    </head> 
    <body leftmargin="0" topmargin="0"> 


                <tr height="15" style="border-top: 1px solid #0F7BBC;"> 
                    <td> 
                        SMS to email test
                    </td> 
                </tr> 


     </body> 
</html> 


------=_Part_110734_170079945.1283532109852--===

Я хочу вытащить «содержание» письма.Итак, мой план таков:

Проверьте, содержит ли тело теги "html".Если нет, я могу читать его нормально (это не электронное письмо в формате HTML).

Если это так, извлеките содержимое между тегами «html».Затем удалите все остальные теги HTML, и «контент» - это то, что осталось.

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

Я пробовал это:

$pattern = '/<html[^>]*>(.*?)<\/html>/i';
preg_match($pattern, $body, $matches);
// my 'content' should be in $matches[1]

Но это не сработало (возможно, потому что $ body содержит символы новой строки и другие пробелы).Тогда я попробовал это:

$pattern = '/<html[^>]*>([.\s]*?)<\/html>/i';
preg_match($pattern, $body, $matches);

Но это тоже не сработало.

Итак, какой шаблон $ я могу использовать, чтобы извлечь весь текст между тегами "html"?

ОБНОВЛЕНИЕ: Я наткнулся на обходной путь - сначала удалите все пробелы:

$body = preg_replace('/\s\s+/', ' ', $body);
$pattern = '/<body[^>]*>(.*?)<\/body>/';

Я подозреваю, что это не самый быстрый или самый эффективный метод, ноэто работает, и это лучшее, что у меня есть до сих пор.Я все же был бы признателен за лучшее решение, если оно есть.

ОБНОВЛЕНИЕ 2: Благодаря предложениям Gumbo, я попытался немного сложнее разобраться в структуре электронной почты.чтобы найти часть, которую я искал, вместо того, чтобы пытаться пересмотреть HTML.Я наконец нашел это: http://docstore.mik.ua/orelly/webprog/pcook/ch17_04.htm,, который объясняет, как делать именно то, что мне нужно.

Ответы [ 4 ]

3 голосов
/ 03 сентября 2010
$pattern = '/<html[^>]*>([^\00]*?)<\/html>/i';

Это сломается, только если в контенте есть 0x00 байт, которого не должно быть.

2 голосов
/ 03 сентября 2010

[.\s] означает либо буквальный ., либо символ пробела. Вам нужно либо (.|\s), либо [\s\S], либо вы просто устанавливаете модификатор s , чтобы . также соответствовал разрывам строки.

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

Но кроме того, вы не должны пытаться угадать диапазон многокомпонентного контента, когда у вас есть разные разделители. Но это не 1016 *. Потому что, если они отсутствуют? Тогда ваша попытка потерпит неудачу. Используйте разделители, определенные самим сообщением: значение border . Поэтому используйте границу, чтобы получить части, и разделите их в первой последовательности CRLF + CRLF, чтобы отделить заголовок от тела.

Но кроме того, почему вы не используете функции IMAP , чтобы получить тело? Я не знаком с PHP IMAP API, но, вероятно, есть функция, которая делает именно то, что вы ищете.

2 голосов
/ 03 сентября 2010

вы можете использовать html-анализатор, например: http://php -html.sourceforge.net /

или использовать strip_tags php.net/strip_tags

1 голос
/ 03 сентября 2010

Вам просто нужно добавить s модификатор , чтобы разрешить . совпадение с новыми строками:

$pattern = '/<html[^>]*>(.*?)<\/html>/si';
preg_match($pattern, $body, $matches);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...