Regex для замены нескольких адресов электронной почты - PullRequest
2 голосов
/ 24 сентября 2011

ОК, вот моя ситуация.У меня есть сайт под управлением WordPress.Мне нужно убедиться, что электронная почта запутана, и поэтому я установил плагин под названием «Изящная электронная почта обфускация».Это уже прекрасно работает.Подвох в том, что я хочу использовать ловушку на случай, если кто-то не будет следовать правилам, которые он устанавливает для ввода адресов электронной почты (т. Е. [email] test@example.com [/email]).

Следующее регулярное выражение прекрасно работает при получении всех писем, НО я не делаюхотите, чтобы он касался тех, которые правильно написаны как [email]test@example.com[/email].Что мне нужно добавить?

// Match any a href="mailto: AND make it optional
$monster_regex = '`(\<a([^>]+)href\=\"mailto\:)?';  

// Match any email address
$monster_regex .= '([^0-9:\\r\\n][A-Z0-9_]+([.][A-Z0-9_]+)*[@][A-Z0-9_]+([.][A-Z0-9_]+)*[.][A-Z]{2,4})'; 

// Now include all its attributes AND make it optional
$monster_regex .= '(\"*\>)?';

// Match any information enclosed in the <a> tag AND make it optional
$monster_regex .= '(.*)?'; 

// Match the closing </a> tag AND make it optional
$monster_regex .= '(\<\/a\>)?`'; 

$monster_regex .= 'im'; // Set the modifiers

preg_match_all($monster_regex, $content, $matches, PREG_SET_ORDER);

Мои данные для тестирования таковы:

<a href = "test@example.com">Tester</a>
test@example.com
<a href = "test@hotmail.com">Hotmail Test</a>
[email]test@example.com]

Вывод, который я получаю, таков:

(
    [0] => Array
        (
            [0] => <a href="mailto:test@example.com">Tester</a>

            [1] => <a href="mailto:
            [2] =>  
            [3] => test@example.com
            [4] => 
            [5] => 
            [6] => ">
            [7] => Tester</a>

        )

    [1] => Array
        (
            [0] => test@example.com

            [1] => 
            [2] => 
            [3] => test@example.com
            [4] => 
            [5] => 
            [6] => 
            [7] => 

        )

    [2] => Array
        (
            [0] => <a href="mailto:test@hotmail.com">Hotmail Test</a>

            [1] => <a href="mailto:
            [2] =>  
            [3] => test@hotmail.com
            [4] => 
            [5] => 
            [6] => ">
            [7] => Hotmail Test</a>

        )

    [3] => Array
        (
            [0] => [email]test@example.com[/email]

            [1] => 
            [2] => 
            [3] => [email]test@example.com
            [4] => 
            [5] => 
            [6] => 
            [7] => [/email]

        )
)

Спасибозаранее.

1 Ответ

0 голосов
/ 25 сентября 2011

То есть вы хотите сопоставить что-либо, похожее на адрес электронной почты, если оно уже не заключено в теги [email]...[/email]? Попробуйте это:

'%(?>\b[A-Z0-9_]+(?:\.[A-Z0-9_]+)*@[A-Z0-9_]+(?:\.[A-Z0-9_]+)*\.[A-Z]{2,4}\b)(?!\s*\[/email\])%i'

NB. Этот ответ решает только вопрос о том, как сопоставить то, что не содержит какой-либо более крупной структуры. Я не собираюсь вступать в дискуссию о том, как (или нужно ли) сопоставлять адреса электронной почты с регулярными выражениями. Я просто извлек ядро ​​регулярного выражения из вопроса, заключил в скобки границы слов (\b) и обернул его в атомную группу ((?>...)).

Как только потенциальное совпадение найдено, отрицательный прогноз утверждает, что за адресом не следует закрывающий тег [/email]. Предполагая, что теги правильно спарены, это означает, что адрес уже правильно помечен. И если они не правильно спарены, то плагин должен поймать его.


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

  • Выражение диапазона A-z появилось в некоторых ваших классах персонажей. Возможно, это просто опечатка, но некоторые люди используют это как выражение для сопоставления прописных или строчных букв. Это ошибка, потому что она также соответствует нескольким знакам препинания, чьи кодовые точки оказываются между двумя буквенными диапазонами. (Я исправил это, когда редактировал вопрос.)

  • Символы <, >, :, ", @, = и / не имеют специального значения в регулярных выражениях и не требуют экранирования. Это ничего не больно, но достаточно трудно для регулярного выражения; зачем указывать лишние косые черты и квадратные скобки, которые вам не нужны?

  • Знак вопроса в (.*)? находится внутри скобок: (.*?). Таким образом, он неохотно сопоставит все до следующего </a>. Если нечего сопоставить, то ничто не сравнится. Если сделать его необязательным, это не только избыточно, это может привести к серьезным потерям производительности .

...