Der schwierige Teil ist Ihre <% ... %>
Anforderung. Es ist eigentlich ziemlich einfach, wenn Sie jeden Teil der URL in Gruppen aufteilen.
href="/images/PDFs/<%=Product.ShortSku %>.pdf"
|_____1_____||__________2_________||_3_|
- Diese Gruppe muss vorhanden sein.
- Diese Gruppe ist optional.
- Wenn Gruppe 2 nicht vorhanden ist, wird Gruppe 3 nicht vorhanden sein. In diesem Fall stimmt Gruppe 1 mit dem gesamten href-Inhalt überein. Wenn Gruppe 2 existiert, ist Gruppe 3 der Rest des href-Inhalts.
Durch das Verständnis über Sie mit diesem für andere Saiten am Ende:
href="/image-ZOOM.aspx?UPPERcasE=someThing"
|________________1_________________|
ich mit diesem Muster endete die Verwendung von benannten Gruppen macht:
@"href=""(?!javascript:)(?=[^""]*[A-Z])(?<Start>[^""<]+)(?<Special><%[^""]+%>)?(?<End>[^""]*)"""
href=""
: passt auf href und öffnet double-quote.
(?!javascript:)
: negative Vorausschau JavaScript-Funktionen zu ignorieren.
(?=[^""]*[A-Z])
: positive Vorausschau, um Großbuchstaben im Inhalt zu finden, um zu kommen. Die [^""]*
entspricht einem beliebigen Zeichen, das kein Doppelzitat ist. Dies geschieht, um zu vermeiden, dass das Ende des Inhalts überschritten wird und unbeabsichtigter Inhalt gierig angepasst wird.
(?<Start>[^""<]+)
: Benannte Gruppe, die mit einem beliebigen Zeichen übereinstimmt, solange es keine doppelte Anführungszeichen oder öffnende spitze Klammer ist. Sehen Sie sich die frühere Darstellung an - die Winkelklammerprüfung stellt sicher, dass wir aufhören, wenn <% ... %>
Inhalt gefunden wird. Wenn dies nicht der Fall ist, wird das Muster fortgesetzt, bis es auf das schließende Doppelzitat trifft.
(?<Special><%[^""]+%>)?
: optional benannte Gruppe zu erfassen <% ... %>
Inhalt. Das nachgestellte ?
markiert diese gesamte Gruppe als optional.
(?<End>[^""]*)
: benannte Gruppe, die mit dem restlichen Inhalt übereinstimmt. Beachten Sie, dass ich *
verwende, um es mit null oder mehr Inhalt übereinstimmen. Dies ermöglicht, dass dieser Teil des Musters als eine optionale Übereinstimmung in dem Fall wirkt, in dem die Gruppe nicht existiert.
""
: Schließen Doppelzitat.
Beispielcode:
string[] inputs =
{
"href=\"/image-ZOOM.aspx?UPPERcasE=someThing\"", // match
"href=\"/image-coorect.aspx\"", // no match, lowercase
"href=\"javascript:function();\"", // no match, javascript
"href=\"/images/PDFs/<%=Product.ShortSku %>.pDf\"", // bypass <% %> content
};
string pattern = @"href=""(?!javascript:)(?=[^""]*[A-Z])(?<Start>[^""<]+)(?<Special><%[^""]+%>)?(?<End>[^""]*)""";
foreach (var input in inputs)
{
Console.WriteLine("{0,6}: {1}", Regex.IsMatch(input, pattern), input);
string result = Regex.Replace(input, pattern,
m => "href=\""
+ m.Groups["Start"].Value.ToLower()
+ m.Groups["Special"].Value
+ m.Groups["End"].Value.ToLower()
+ "\"");
Console.WriteLine("Result: " + result);
Console.WriteLine();
}
Dieses eine Lambda anstelle des MatchEvaluator
verwendet. Im Wesentlichen rekonstruieren wir die Zeichenfolge und beziehen uns auf die benannten Gruppen, indem wir die Groß-/Kleinschreibung der Gruppen ändern, die wir ändern möchten. Der subtile Schlüssel zu diesem Code ist, dass, wenn eine Gruppe nicht übereinstimmt, wir immer noch darauf verweisen können und es uns einfach einen leeren String geben wird. Auch dies ist möglicherweise nicht offensichtlich aus dem Code, aber wenn eine Übereinstimmung fehlschlägt, wird die ursprüngliche Zeichenfolge unverändert von Regex.Replace
zurückgegeben.
Wenn Sie nur in Kleinbuchstaben konvertieren, warum ist es dann von Bedeutung, wenn sie mit Links übereinstimmt, die bereits in Kleinbuchstaben geschrieben sind? Effektiv würde dem sowieso nichts passieren. – mellamokb
Das Muster, das Sie geben, stimmt nicht mit href = "/ image-coorect.aspx" für mich überein. Können Sie Ihren Testcode anzeigen? – mellamokb
Das stimmt, aber wenn ich <% %> innerhalb des Links habe ich nicht wollen, dass es in Kleinbuchstaben konvertiert – Sergey