2010-11-23 3 views
2

Мне нужно получить адрес электронной почты с привязки с атрибутом mailto с регулярным выражением.preg_match для извлечения mailto на якорь

этот шаблон: (.*)<a\s(.*?)(.*)\s*href\=['"]mailto:([-a-z0-9_]+)@([a-z0-9-]+).([a-z]+)['"]>(.*)</a>(.*)

Работает в регулярных выражениях тренера, хотя он не работает с PHP.

Код:

preg_match("'(.*)<a (.*?)(.*) *href\=['\"]mailto:([-a-z0-9_]+)@([a-z0-9-]+).([a-z]+)['\"]>(.*)</a>(.*)'si", "<a href=\"mailto:[email protected]\"">Some email</a>", $matches); 

print_r($matches); 

Так почему doenst это работает в PHP?

+0

В качестве примечания: вам необходимо добавить `+` в качестве символа в классе символов :([-a-z0-9 _] +), потому что некоторые люди используют их для фильтрации триггеров в адресах электронной почты, например, [email protected] – Keng 2010-11-23 16:41:41

+0

Все эти `. *` приведут к ужасному поведению производительности. – Gumbo 2010-11-23 16:41:44

+0

примечание стороны: хотя редко, вполне приемлемо иметь адрес электронной почты, такой как: hell.o \ @ world @ two.ats.com Возможно, вам лучше снимать более простое регулярное выражение, если не будет электронные письма. Зависит от того, что вы делаете с ними. – DampeS8N 2010-11-23 16:43:34

ответ

4

PHP’s PCRE требуется регулярное выражение быть обернуты в delimiters, которые отделяют образец от факультативного modifiers. В этом случае используется первый неалфавитно-цифровой символ (то есть '), поэтому шаблон фактически равен (.*)<a (.*?)(.*) *href\=[, а остальные рассматриваются как модификаторы. И это недопустимое регулярное выражение, так как [ не экранируется должным образом, а остальные не являются допустимыми модификаторами.

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

Но кроме того, попытка проанализировать HTML с регулярными выражениями очень подвержена ошибкам. В вашем случае использование этого количества .* также приведет к ужасному поведению производительности (это связано с тем, как обрабатываются регулярные выражения).

Лучше использовать правильный HTML-парсер, который возвращает DOM, которая может быть запрошена как PHP’s DOM library:

$doc = new DomDocument(); 
$doc->loadHTML($str); 
foreach ($doc->getElementsByTagName("a") as $a) { 
    if ($a->hasAttribute("href")) { 
     $href = trim($a->getAttribute("href")); 
     if (strtolower(substr($href, 0, 7)) === 'mailto:') { 
      $components = parse_url($href); 
     } 
    } 
} 
1

Вашего разделитель цитата ', и есть некоторые случаи его в регулярном выражении:

preg_match("'(.*)<a (.*?)(.*) *href\=['\"]mailto:([-a-z0-9_]+)@([a-z0-9-]+).([a-z]+)['\"]>(.*)</a>(.*)'si", "<a href=\"mailto:[email protected]\"">Some email</a>", $matches); 
            ^           ^

избежать их (т.е .: \') или изменить разделитель.

0
if (preg_match('#<a\s.*?href=[\'"]mailto:([A-Z0-9._%+-][email protected][A-Z0-9.-]+\.[A-Z]{2,6})[\'"].*?>.*?</a>#i', $subject, $regs)) { 
    $result = $regs[0]; 
} else { 
    $result = ""; 
}
Смежные вопросы