Регулярное выражение гиперссылки, включая http (s): // не работает в C # - PullRequest
0 голосов
/ 12 марта 2010

Я думаю, что это достаточно отличается от похожих вопросов, чтобы оправдать новый.

У меня есть следующее регулярное выражение для сопоставления начинающих тегов гиперссылок в HTML, включая часть http (s): // во избежание mailto: links

<a[^>]*?href=[""'](?<href>\\b(https?)://[^\[\]""]+?)[""'][^>]*?>

Когда я запускаю это через Nregex (с удаленным экранированием), оно соответствует правильно для следующих тестовых случаев:

<a href="http://www.bbc.co.uk">

<a href="http://bbc.co.uk">

<a href="https://www.bbc.co.uk">

<a href="mailto:rory@domain.com">

Однако, когда я запускаю это в своем коде C #, это не получается. Вот соответствующий код:

public static IEnumerable<string> GetUrls(this string input, string matchPattern)
    {
        var matches = Regex.Matches(input, matchPattern, RegexOptions.Compiled | RegexOptions.IgnoreCase);
        foreach (Match match in matches)
        {
            yield return match.Groups["href"].Value;
        }
    }

И мои тесты:

@"<a href=""https://www.bbc.co.uk"">bbc</a>".GetUrls(StringExtensions.HtmlUrlRegexPattern).Count().ShouldEqual(1);

@"<a href=""mailto:rory@domain.com"">bbc</a>".GetUrls(StringExtensions.HtmlUrlRegexPattern).Count().ShouldEqual(0);

Проблема, похоже, в добавленной мной части \\b(https?)://, удаление которой проходит обычный тест URL, но не проходит mailto: test.

Кто-нибудь пролил свет?

Ответы [ 3 ]

1 голос
/ 12 марта 2010

Вы пишете регулярное выражение, как это?

@"<a[^>]*?href=[""'](?<href>\\b(https?)://[^\[\]""]+?)[""'][^>]*?>"

Если это так, у вас слишком много обратной косой черты в границе слова. Поскольку это дословный строковый литерал, компилятор регулярных выражений видит две обратных косых черты, как вы их написали, поэтому он думает, что вы ищете буквальную последовательность \b.

Но вам все равно не нужно использовать границу слова там. Вы уже указали, что протоколу должен предшествовать одинарная или двойная кавычка, поэтому ему не может предшествовать символ слова.

1 голос
/ 12 марта 2010

Проблема в том, что ваше регулярное выражение действительно ищет что-то вроде <a href="\bhttps://.... Если вы удалите \\b (что не нужно), оно должно работать. Используйте это вместо:

<a[^>]*?href=[""'](?<href>(https?)://[^\[\]""]+?)[""'][^>]*?>
0 голосов
/ 12 марта 2010

В качестве общего совета при работе с регулярными выражениями вам нужно разбить их на составные части и заставить каждый фрагмент работать правильно. Затем вы можете сосредоточиться на их сборке в соответствии с вашими данными. Иногда это может быть трудно сделать - особенно со сложными выражениями, включающими trackback или lookahead, но ваш случай достаточно прост, чтобы вы могли разбить выражение на части, которые работают индивидуально.

Я думаю, что это должно работать:

@"(https?):[/][/][^\[\]""]+?)[""'][^>]*?"

Вам не нужно экранировать / символов в регулярных выражениях, но это не помешает заключить их в [ ] селектор групп.

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