Как я могу сделать это регулярное выражение правильно? - PullRequest
1 голос
/ 26 октября 2009

Учитывая это регулярное выражение:

^((https?|ftp):(\/{2}))?(((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}
(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?))|(((([a-zA-Z0-9]+)(\.)*?))(\.)([a-z]{2}
|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum){1})

Переформатировано для удобства чтения:

@"^((https?|ftp):(\/{2}))?" + // http://, https://, ftp:// - Protocol Optional
@"(" + // Begin URL payload format section
@"((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" + // IPv4 Address support
@")|("+ // Delimit supported payload types
@"((([a-zA-Z0-9]+)(\.)*?))(\.)([a-z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum){1}" + // FQDNs
@")"; // End URL payload format section

Как я могу заставить его потерпеть неудачу (т. Е. Не совпадать) в этом тестовом примере "fail"?

http://www.google

Поскольку я указываю {1} в разделе TLD, я думаю, что он потерпит неудачу без расширения. Я не прав?

Редактировать: Это мои условия PASS:

Это мои условия неудачи:

Ответы [ 5 ]

4 голосов
/ 26 октября 2009

Я выброшу альтернативное предложение. Возможно, вы захотите использовать комбинацию синтаксического анализа встроенного класса System.Uri и нескольких целевых регулярных выражений (или простых проверок строк при необходимости).

Пример:

string uriString = "...";

Uri uri;
if (!Uri.TryCreate(uriString, UriKind.Absolute, out uri))
{
    // Uri is totally invalid!
}
else
{
    // validate the scheme
    if (!uri.Scheme.Equals("http", StringComparison.OrdinalIgnoreCase))
    {
        // not http!
    }

    // validate the authority ('www.blah.com:1234' portion)
    if (uri.Authority // ...)
    {
    }

    // ...
}
3 голосов
/ 26 октября 2009

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

2 голосов
/ 26 октября 2009

Вы должны заставить ваше регулярное выражение совпадать до конца строки. Добавьте $ в самом конце. В противном случае ваше регулярное выражение, вероятно, просто соответствует http://, или что-то еще короче всей вашей строки.

1 голос
/ 26 октября 2009

Проблема проверки URL была решена * много раз. Я предлагаю вам использовать класс System.Uri, он проверяет больше случаев, чем вы можете потрясти палкой.

Код Uri uri = new Uri("<a href="http://whatever" rel="nofollow noreferrer">http://whatever</a>"); выдает UriFormatException, если он не проходит проверку. Это, вероятно, то, что вы хотели бы.

*) Или вроде решено. На самом деле довольно сложно определить, что является действительным URL.

0 голосов
/ 19 августа 2013

Все дело в определениях, «действительный URL» должен предоставлять вам IP-адрес, когда вы выполняете поиск DNS. IP-адрес должен быть подключен, и при отправке запроса вы получите ответ в виде HTML-информации, которую вы можете использовать.

Итак, мы ищем «действительный формат URL», и именно здесь system.uri очень пригодится. НО, если URL-адрес скрыт в большом фрагменте текста, вы сначала хотели бы найти что-то, что подтверждает правильность URL-формата.

То, что отличает URL от любого читаемого текста, это точка, за которой не следует пробел. «123.com» может проверяться как реальный URL.

Использование регулярного выражения

[a-z_\.\-0-9]+\.[a-z]+[^ ]*

, чтобы найти любой возможный допустимый URL-адрес в тексте, а затем выполнить проверку system.uri, чтобы убедиться, что это правильный формат URL, а затем выполнить поиск. Только когда поиск даст вам результат, вы узнаете, что URL действителен.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...