Возможно ли это без использования регулярного выражения?
Например, я хочу проверить, что строка является допустимым доменом:
domain-name abcd example
Действительные домены. Конечно, они недействительны:
domaia@name ab$%cd
И так далее. Поэтому в основном это должно начинаться с буквенно-цифрового символа, тогда может быть больше символов alnum плюс дефисс. И он должен заканчиваться символом alnum.
Если это невозможно, можете ли вы предложить мне шаблон регулярного выражения для этого?
РЕДАКТИРОВАТЬ:
Почему это не работает? Я неправильно использую preg_match?
$domain = '@djkal'; $regexp = '/^[a-zA-Z0-9][a-zA-Z0-9\-\_]+[a-zA-Z0-9]$/'; if (false === preg_match($regexp, $domain)) { throw new Exception('Domain invalid'); }
<?php function is_valid_domain_name($domain_name) { return (preg_match("/^([az\d](-*[az\d])*)(\.([az\d](-*[az\d])*))*$/i", $domain_name) //valid chars check && preg_match("/^.{1,253}$/", $domain_name) //overall length check && preg_match("/^[^\.]{1,63}(\.[^\.]{1,63})*$/", $domain_name) ); //length of each label } ?>
Тестовые случаи:
is_valid_domain_name? [a] Y is_valid_domain_name? [0] Y is_valid_domain_name? [ab] Y is_valid_domain_name? [localhost] Y is_valid_domain_name? [google.com] Y is_valid_domain_name? [news.google.co.uk] Y is_valid_domain_name? [xn--fsqu00a.xn--0zwm56d] Y is_valid_domain_name? [goo gle.com] N is_valid_domain_name? [google..com] N is_valid_domain_name? [google.com ] N is_valid_domain_name? [google-.com] N is_valid_domain_name? [.google.com] N is_valid_domain_name? [<script] N is_valid_domain_name? [alert(] N is_valid_domain_name? [.] N is_valid_domain_name? [..] N is_valid_domain_name? [ ] N is_valid_domain_name? [-] N is_valid_domain_name? [] N
При этом вы не только будете проверять, имеет ли домен допустимый формат, но также и если он активен / имеет назначенный ему IP-адрес.
$domain = "stackoverflow.com"; if(filter_var(gethostbyname($domain), FILTER_VALIDATE_IP)) { return TRUE; }
Обратите внимание, что для этого метода требуется, чтобы записи DNS были активными, поэтому, если вам требуется, чтобы строка домена была проверена без использования в DNS, используйте метод регулярных выражений, заданный листвой выше.
Также эта функция не предназначена для проверки строки URL, для которой используется FILTER_VALIDATE_URL. Мы не используем FILTER_VALIDATE_URL для домена, потому что строка домена не является допустимым URL.
используйте checkdnsrr http://php.net/manual/en/function.checkdnsrr.php
$domain = "stackoverflow.com"; checkdnsrr($domain , "A"); //returns true if has a dns A record, false otherwise
Во-первых, вы должны уточнить, имеете ли вы в виду:
Причиной разграничения является то, что метка может технически включать любые символы, включая NUL, @
и ' .
' персонажи. DNS поддерживает 8 бит, и вполне возможно иметь файл зоны, содержащий запись с надписью « an\0odd\.l@bel
». Разумеется, это не рекомендуется, не в последнюю очередь потому, что людям будет сложно рассказать о точке внутри ярлыка от разделяющих этикеток, но это законно.
Однако для URL-адресов требуется имя хоста , и они регулируются RFC 952 и 1123. Действительные имена хостов являются подмножеством доменных имен. В частности, допускаются только буквы, цифры и дефис. Кроме того, первый и последний символы не могут быть дефисом. RFC 952 не разрешал номер для первого символа, но RFC 1123 впоследствии смягчил это.
Следовательно:
a
– действительный 0
– действительный a-
– недействительный ab
– действительный xn--dasdkhfsd
– действительный (punycode encoding of IDN) Сверху моей головы я не думаю, что можно аннулировать пример с помощью простого простого регулярного выражения. Лучшее, что я могу придумать, чтобы проверить один ярлык хоста :
if (preg_match('/^[az\d][az\d-]{0,62}$/i', $label) && !preg_match('/-$/', $label)) { # label is legal within a hostname }
Чтобы еще больше усложнить ситуацию, некоторые записи в имени домена (обычно SRV
записи) используют метки с префиксом подчеркивания, например _sip._udp.example.com
. Это не имена хостов, а юридические имена доменов.
Я думаю, как только вы выделили доменное имя, скажем, используя идею Эрклана:
$ myUrl = "http://www.domain.com/link.php"; $ myParsedURL = parse_url ($ myUrl); $ myDomainName = $ myParsedURL ['host'];
вы можете использовать:
if (false === filter_var ($ myDomainName, FILTER_VALIDATE_URL)) { // неудачный тест }
Функции PHP5s Filter для такой цели я бы подумал.
Я точно понимаю, что он не отвечает на ваш вопрос, поскольку он не использует Regex.
Вот еще один способ без регулярного выражения.
$myUrl = "http://www.domain.com/link.php"; $myParsedURL = parse_url($myUrl); $myDomainName= $myParsedURL['host']; $ipAddress = gethostbyname($myDomainName); if($ipAddress == $myDomainName) { echo "There is no url"; } else { echo "url found"; }
Регулярное выражение – наиболее эффективный способ проверки валидации домена. Если вы мертвы, если не используете регулярное выражение (какое ИМО глупо), вы можете разделить каждую часть домена:
Затем вам нужно будет проверить каждый символ в каком-то цикле, чтобы убедиться, что он соответствует допустимому домену.
Как я уже сказал, гораздо эффективнее использовать регулярное выражение.
Ваше регулярное выражение прекрасно, но вы не используете preg_match
правильно. Он возвращает int
(0 или 1), а не логическое. Просто напишите if(!preg_match($regex, $string)) { ... }
Если вы не хотите использовать регулярные выражения, вы можете попробовать следующее:
$str = 'domain-name'; if (ctype_alnum(str_replace('-', '', $str)) && $str[0] != '-' && $str[strlen($str) - 1] != '-') { echo "Valid domain\n"; } else { echo "Invalid domain\n"; }
но, как сказал regexp, это лучший инструмент для этого.
Если вы хотите проверить, существует ли конкретное доменное имя или IP-адрес, вы также можете использовать checkdnsrr
Вот документ http://php.net/manual/en/function.checkdnsrr.php
Допустимый домен – это то, что я могу зарегистрировать или, по крайней мере, что-то похожее на то, что я могу его зарегистрировать. Именно по этой причине мне нравится отделять это от «localhost» -names.
И, наконец, меня заинтересовал главный вопрос, если бы избежать Regex было бы быстрее, и это мой результат:
<?php function filter_hostname($name, $domain_only=false) { // entire hostname has a maximum of 253 ASCII characters if (!($len = strlen($name)) || $len > 253 // .example.org and localhost- are not allowed || $name[0] == '.' || $name[0] == '-' || $name[ $len - 1 ] == '.' || $name[ $len - 1 ] == '-' // a.de is the shortest possible domain name and needs one dot || ($domain_only && ($len < 4 || strpos($name, '.') === false)) // several combinations are not allowed || strpos($name, '..') !== false || strpos($name, '.-') !== false || strpos($name, '-.') !== false // only letters, numbers, dot and hypen are allowed /* // a little bit slower || !ctype_alnum(str_replace(array('-', '.'), '', $name)) */ || preg_match('/[^az\d.-]/i', $name) ) { return false; } // each label may contain up to 63 characters $offset = 0; while (($pos = strpos($name, '.', $offset)) !== false) { if ($pos - $offset > 63) { return false; } $offset = $pos + 1; } return $name; } ?>
Результаты тестов сравниваются с функцией липучки и 10000 итерациями ( полные результаты содержат много вариантов кода. Было интересно найти самые быстрые.):
filter_hostname($domain);// $domains: 0.43556308746338 $real_world: 0.33749794960022 is_valid_domain_name($domain);// $domains: 0.81832790374756 $real_world: 0.32248711585999
$real_world
не содержит крайних длинных доменных имен для получения лучших результатов. И теперь я могу ответить на ваш вопрос: с использованием ctype_alnum()
было бы возможно реализовать его без регулярного выражения, но поскольку preg_match()
был быстрее, я бы предпочел это.
Если вам не нравится тот факт, что «local.host» является действительным доменным именем, используйте эту функцию вместо того, чтобы валиды против публичного списка tld. Может быть, кто-то найдет время, чтобы объединить оба.
Я знаю, что это старый вопрос, но это был первый ответ на поиск Google, поэтому он кажется актуальным. У меня недавно была такая же проблема. Решение в моем случае состояло в том, чтобы просто использовать публичный список суффикса:
https://publicsuffix.org/learn/
Предлагаемые перечисленные конкретные языковые библиотеки должны обеспечивать простоту проверки не только формата домена, но и действительности домена верхнего уровня.
Проверьте функцию php checkdnsrr
function validate_email($email){ $exp = "^[az\'0-9]+([._-][az\'0-9]+)*@([a-z0-9]+([._-][a-z0-9]+))+$"; if(eregi($exp,$email)){ if(checkdnsrr(array_pop(explode("@",$email)),"MX")){ return true; }else{ return false; } }else{ return false; } }
Это проверка имени домена в javascript:
<script> function frmValidate() { var val=document.frmDomin.name.value; if (/^[a-zA-Z0-9][a-zA-Z0-9-]{1,61}[a-zA-Z0-9](?:\.[a-zA-Z]{2,})+$/.test(val)){ alert("Valid Domain Name"); return true; } else { alert("Enter Valid Domain Name"); val.name.focus(); return false; } } </script>
Это просто. У некоторых php egnine есть проблема с split (). Этот код ниже будет работать.
<?php $email = "vladimiroliva@ymail.com"; $domain = strtok($email, "@"); $domain = strtok("@"); if (@getmxrr($domain,$mxrecords)) echo "This ". $domain." EXIST!"; else echo "This ". $domain." does not exist!"; ?>