Hallo zusammen
Wiedermal eine kleine Regex-Aufgabe, die mir zugetragen wurde. Ich verwende zusätzlich das Regex-Lab von herbivore (vielen Dank für das super Tool!!) aber ich sehe das Problem nicht.
Regex:
var tagRegex = new Regex(@"([^<>]*(<translate>[^<>]*</translate>))*", RegexOptions.Compiled);
Input: "<test>test text</test>"
if (tagRegex.IsMatch("<test>test text</test>"))
{
return "gefunden";
}
Und da findet er mir immer was 😦 (das genaue problem: Wenn ein XML-Tag im Text vorkommt, dann darf nur "translate" drin stehen.. )
Weiss jemand Rat?
Merci
Hallo martinO,
durch die Verwendung von * findest du auch Stellen, die Null-Zeichen lang sind. Und die gibt es in jedem Input-String, an jeder Stelle zwischen zwei Zeichen sowie vor dem ersten und nach dem letzten Zeichen, also bei einem String der Länge n sind es n+1 Stellen. Wobei dir Regex-Lab ja anzeigt, an welcher Stelle der Match gefunden wird und wie lang er ist.
Verwendet + statt *.
herbivore
Hallo herbivore
Vielen Dank für die Antwort. Ich hab die Regex jetzt mit dem + angepasst.
var tagRegex = new Regex(@"([^<>]*(<translate>[^<>]*</translate>))+", RegexOptions.Compiled);
Nun findet er den "<test>text</test>" Input string nicht mehr, was auch gut ist. Jedoch findet er mir keinen string, der nur Zeichen entält ("hallo welt") - ist auch erlaubt.
var tagRegex = new Regex(@"([^<>]*|(<translate>[^<>]*</translate>))+", RegexOptions.Compiled);
Diese findet mir zwar "hallo welt", aber auch wieder "<test>text</test>" - wegen dem "|"... Ich switche schon länger zwischen zwei Unit Tests - mal funktioniert der eine, dann wieder der ander 😦
Hallo martinO,
Diese findet mir zwar "hallo welt", aber auch wieder "<test>text</test>"
nö, er findet nicht "<test>text</test>", sondern er finden wieder einen leeren Match, weil du in dem entsprechenden Teilausdruck wieder * statt + verwendet hast.
Wenn du willst, dass der Pattern nur auf den gesamten Text passt und nicht auf Teile davon, verwende ^ und $.
herbivore
Hallo herbivore
Vielen Dank für den Tipp mit dem $.
Für alle, die auf dieses Problem mal stossen:
Die Aufgabe: Ein Text darf XML Tags beinhalten. Wenn er XML Tags beinhaltet, dann einzig das translate-Tag.
Beispiele (aus meinen unit tests):
"Reiner Text" => gut
"prefix <translate>text</translate> suffix" => gut
"prefix <translate>text</translate>" => gut
"<translate>text</translate> suffix" => gut
"prefix <translate>text</translate><translate>text</translate> suffix" => gut
"prefix <translate>text</translate>asdf<translate>text</translate> suffix" => gut
"<a>a</a>" => nicht gut
"adf <b>a</b>" => nicht gut
Die Lösung:
var tagRegex = new Regex(@"^[^<>]*([^<>]*(<translate>[^<>]*</translate>)[^<>]*)*$", RegexOptions.Compiled);
if (tagRegex.IsMatch(this.value))
{
return "gut";
}
return "nicht gut";