Подтвердить что ты не робот

RegEx не работает с .NET, но работает с другими реализациями RegEx

Я пытаюсь сопоставить строки, которые выглядят так:

http://www.google.com

Но если это происходит в более широком контексте, например:

<a href="#" onclick="location.href='http://www.google.com'; return false;"> http://www.google.com </a>

У меня есть регулярное выражение, которое выполняет эту работу в нескольких разных версиях RegEx, которые я тестировал (PHP, ActionScript) выглядит следующим образом:

(?<!["'>]\b*)((https?://)([A-Za-z0-9_=%&@?./-]+))\b

Вы можете увидеть, как он работает здесь: http://regexr.com?36g0e

Проблема в том, что данный RegEx не работает корректно в .NET.

private static readonly Regex fixHttp = new Regex(@"(?<![""'>]\b*)((https?://)([A-Za-z0-9_=%&@?./-]+))\b", RegexOptions.IgnoreCase);
private static readonly Regex fixWww = new Regex(@"(?<=[\s])\b((www\.)([A-Za-z0-9_=%&@?./-]+))\b", RegexOptions.IgnoreCase);

public static string FixUrls(this string s)
{
    s = fixHttp.Replace(s, "<a href=\"$1\">$1</a>");
    s = fixWww.Replace(s, "<a href=\"http://$1\">$1</a>");
    return s;
}

В частности,.NET, похоже, не обращает внимания на первый \b*. Другими словами, он правильно не соответствует этой строке:

<a href="#" onclick="location.href='http://www.google.com'; return false;">http://www.google.com</a>

Но он неправильно соответствует этой строке (обратите внимание на дополнительные пробелы):

<a href="#" onclick="location.href='http://www.google.com'; return false;"> http://www.google.com </a>

Любые идеи относительно того, что я делаю неправильно или как это работает?

4b9b3361

Ответ 1

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

Я не совсем уверен, что происходит не так, но, оказывается, в .NET мне нужно было заменить \b* на \s*. \s*, похоже, не работает с другими механизмами RegEx (я только немного тестировал), но он корректно работает с .NET. Документация, которую я прочитал около \b, заставит меня поверить, что она должна совпадать с пробелами, ведущими к слову, но, возможно, я неправильно понял, или, может быть, есть некоторые странности вокруг захватов, которые разные механизмы обрабатывают по-разному.

Во всяком случае, это мой последний RegEx:

(?<!["'>]\s*)((https?:\/\/)([A-Za-z0-9_=%&@\?\.\/\-]+))\b

Я не понимаю, что делалось неправильно, чтобы дать реальный контекст, почему это изменение работает, и мне не нравится RegExes, что я не могу полностью оправдать время его выяснения, но, возможно, это поможет кому-то иначе в итоге: -).