Perl Regex Электронная почта TLD

у меня есть этот код:

    if ( $Mail =~ /$Tld{$_}/ ) {
        $TldFound = 1;      
    }

Переменная $Mail имеет, например, информацию «[email protected]». Переменная $Tld имеет информацию ".com". Как я могу вырезать переменную $Mail, чтобы остался только tld .com?


person MrWein    schedule 15.08.2015    source источник
comment
возможный дубликат regex - извлечь доменное имя и TLD   -  person d0nut    schedule 16.08.2015
comment
У вас нет конкретной проблемы, кроме незнания Perl. Вы не должны изучать язык постепенно, полагаясь на добрую волю людей из Stack Overflow, и я считаю, что вам нужен учебник по Perl   -  person Borodin    schedule 16.08.2015
comment
Вы можете сделать хакерское решение с @.*\.(.*) Это сохранит все после последнего . в $1 или \1. Однако для иностранных доменов это не сработает, или, скорее, вам также понадобится домен второго уровня, как я подозреваю (например, co.uk).   -  person chris85    schedule 16.08.2015


Ответы (2)


Вы должны использовать Email::Address для анализа адресов электронной почты.

Чтобы с уверенностью извлечь TLD, требуется список того, что вы считаете TLD. Например, считать ли .co.uk или .com.tr? Или вам просто нужна последняя строка символов без точек?

Если вы ограничиваете свое внимание 2–3-символьными TLD, такими как .co, .com, .io, .net, .org, .us и т. д., вы можете сделать my ($tld) = ($email =~ /[.] ([a-z]{2,3}) \z/x);, а затем проверить с помощью if ($tld and ($tld eq 'com')) { ... } и т. д., но вам действительно нужен хороший список допустимых строк, которые можно TLD: Net::Domain::TLD, Mozilla::PublicSuffix.

person Sinan Ünür    schedule 16.08.2015
comment
Хотя я согласен с вашим первым предложением, ваш ответ создает ненужную сложность, не требуемую исходным вопросом. Ваш подход потребует исчерпывающего списка TLD, что является излишним для этой конкретной проблемы. - person Todd A. Jacobs; 16.08.2015
comment
Я в основном обнаружил, что когда люди говорят, что не требуется, они в конечном итоге проводят свои выходные и праздники, борясь с пожарами, которые позже вызывают. Вам не нужен исчерпывающий список: достаточно одного, достаточного для решения проблемы. Даже тогда, что это? Пять минут гугления? - person brian d foy; 28.10.2015

Наивные решения для регулярных выражений

Следующие решения решат вашу проблему, как опубликовано, но не предназначены для решения всех возможных крайних случаев. Комплексный анализ адресов электронной почты нетривиален и требует анализатора, такого как Email::Address если вы хотите справиться со всей сложностью RFC.

Печать вашего TLD из строки

Поскольку вы уже знаете строку, которую хотите напечатать в случае успеха (например, ".com"), вам на самом деле не нужен результат совпадения с регулярным выражением; вы можете распечатать строку, хранящуюся в $Tld, если совпадение истинно, используя условие после утверждения. Например:

$Mail = '[email protected]';
$Tld  = '.com';

print "$Tld\n" if $Mail =~ /${Tld}$/;

Это будет правильно печатать:

.com

Печать матча

Если вы действительно хотите полное совпадение, есть несколько способов сделать это. Один из способов — использовать специальную переменную $&:

$Mail = '[email protected]';
$Tld  = '.com';

if ($Mail =~ /${Tld}$/) {
    print "$&\n";
}

Это также будет правильно печатать:

.com

Разделение строки

Все предыдущие примеры решат вашу проблему, как было опубликовано, но лучшее общее решение, если не считать синтаксического анализатора, состоит в том, чтобы действительно разделить TLD и рассматривать последний сегмент домена как непроверенный TLD. В Ruby есть очень удобный раздел String#rpartition. метод, но я не знаю о подобной функции в Perl. Тем не менее, вы можете использовать привязанное соответствие, чтобы добиться того же самого. Например:

$Mail = '[email protected]';

$Mail =~ /(\.[[:alpha:]]+)$/;
print "$1\n";

Если вам нужно проверить TLD на соответствие ожидаемому значению, например .com, вы можете сравнить его со строкой или переменной. Например:

$Mail = '[email protected]';
$Tld  = '.com';

$Mail =~ /(\.[[:alpha:]]+)$/;
print "$1\n" if $1 eq $Tld
person Todd A. Jacobs    schedule 15.08.2015
comment
Этот ответ настолько неверен во многих отношениях ... Во-первых, как вы думаете, что $Mail содержит после $Mail = "[email protected]"? Во-вторых, понимаете ли вы, что . является особенным в шаблоне регулярного выражения? В-третьих, что, если $Mail содержит [email protected]? Какой смысл публиковать подобные вещи? - person Sinan Ünür; 16.08.2015
comment
@SinanÜnür Спасибо за разглагольствования и за то, что публично продемонстрировали отсутствие социальных навыков в Stack Overflow. Ответ работает, предоставляет автономные примеры и решит опубликованную проблему OP и не предназначен для решения всех мыслимых крайних случаев. Однако ответ был обновлен, чтобы привязать регулярное выражение, поскольку я согласен, что оно /.com/ будет слишком широким. - person Todd A. Jacobs; 16.08.2015
comment
Должен ли сопоставление шаблона быть успешным, если $Mail заканчивается на ".com\n"? Кроме того, понимаете ли вы, что . является особенным в шаблоне регулярного выражения? - person Sinan Ünür; 16.08.2015
comment
Среди проблем, которые отмечает Синан, я советую не использовать привязку к концу строки, $, так как теперь это может изменить поведение с флагами регулярных выражений по умолчанию. Используйте \z, если вы хотите конец строки. - person brian d foy; 28.10.2015