2013-09-26 10 views
12

Próbuję dopasować ciągi, które wyglądają tak:RegEx nie działa z .NET, ale nie z innych regex wdrożeń

http://www.google.com 

Ale nie jeśli występuje w szerszym kontekście tak:

<a href="http://www.google.com"> http://www.google.com </a> 

regex mam że spełnia swoje zadanie w kilka różnych silników rEGEX Przetestowałem (PHP, ActionScript) wygląda następująco:

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

Możesz zobaczyć, że działa tutaj: http://regexr.com?36g0e

Problem polega na tym, że ten konkretny regeks nie działa poprawnie w .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; 
} 

Konkretnie, .NET nie wydaje się być zwrócenie uwagi na pierwszej \b*. Innymi słowy, to właściwie nie pasuje ten ciąg:

<a href="http://www.google.com">http://www.google.com</a> 

Ale to nieprawidłowo pasuje ten ciąg (uwaga na dodatkowe spacje):

<a href="http://www.google.com"> http://www.google.com </a> 

Jakieś pomysły co do tego, co robię źle lub jak to obejść?

+0

Nie ma zamiany lub dopasowania w łączu regexr ... I nie powinieneś umieszczać kwantyfikatorów na granicach słów. W .NET (myślę tutaj o C#), musisz uciec podwójnym cudzysłowom z podwójnymi cudzysłowami, aby "" stało się "" ". – Jerry

+0

@Jerry - Tak, robię to wszystko w moim rzeczywistym C# –

+0

Pamiętam, że korzystałem z niektórych narzędzi RE i mieli możliwość wyboru silnika wykonującego RE.A był silnik .Net, ponieważ wykonywał RE w różny sposób –

Odpowiedz

4

Czekałem na jednym z ludzi, którzy faktycznie początkowo odpowiedzieli na to pytanie pop odpowiedź tutaj, ale ponieważ nie mają, rzucę go w.

Nie jestem precyzyjnie pewnie, co poszło nie tak, ale okazało się, że w .NET, musiałem wymienić \b* na \s*. \s* wydaje się nie działać z innymi silnikami RegEx (zrobiłem tylko trochę testów), ale działa poprawnie z .NET. Dokumentacja, którą przeczytałem pod numerem \b, doprowadziłaby mnie do przekonania, że ​​powinna ona pasować do spacji prowadzącej do słowa, ale być może mnie źle zrozumiałem, lub może jest kilka dziwactw związanych z przechwytywaniem, że różne silniki radzą sobie inaczej.

W każdym razie, to jest moja ostateczna RegEx:

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

Nie rozumiem, co się dzieje źle na tyle dobrze, aby dać żadnej realnej kontekst dlaczego ta zmiana działa, a ja lubię regexes wystarczy, że nie może całkiem usprawiedliwić czasu na zastanowienie się, ale może pomoże to komuś innemu :-).