2017-06-06 4 views
1

Wie kann ich "enthält" in der Regex ("Enthält" oder "% like%")?Regex Enthält im XML-Element

Ich habe einen regulären Ausdruck den XML-Knoten mit genauer Text entsprechen:

<([\w]+)[^>]*>sample<\/\1> 

Es ergibt ich den genauen Knotennamen, aber ich mag die Regex anwenden wie in C# und SQL (%LIKE%).

Text:

<Part>this is sample part</Part> 
    <Remarks>this is sample remark</Remarks> 
    <Notes>this is sample notes</Notes> 
    <Desc>sample</Desc> 

Erwartete regex Ergebnis sollte alle oben genannten Knoten, kehren aber zur Zeit gibt es nur den letzten Knoten.

Ich erstellte a sample here to test.

+2

Falsches Werkzeug für den Job. Regex ist kein XML-Parser * und kann es auch nicht sein *. – spender

+3

Warum verwenden Sie XPath nicht? '// * [contains (text()," sample ")]/local-name()' –

+0

@ WiktorStribiżew danke, versuche ich mit Xpath –

Antwort

2

Sie XDocument verwenden XML so zu analysieren:

var s = @"<?xml version=""1.0""?> 
    <root> 
    <Part>this is sample part</Part> 
    <Remarks>this is sample remark</Remarks> 
    <Notes>this is sample notes</Notes> 
    <Desc>sample</Desc> 
    </root>"; 
var document = XDocument.Parse(s); 
var names = document.Descendants() 
       .Elements() 
       .Where(x => x.Value.Contains("sample")) // all nodes with text having sample 
       .Select(a => a.Name.LocalName); // return the local names of the nodes 
Console.WriteLine(string.Join("\n", names)); 

Er druckt:

enter image description here

Die Gleiches kann mit einem XPath erreicht werden:

var names2 = document.Root.XPathSelectElements("//*[contains(text(), \"sample\")]"); 
var results = names2.Select(x => x.Name.LocalName)); 

fallen zurück, falls regex die XML nicht gültig ist,

<(?:\w+:)?(\w+)[^<]*>[^<]*?sample[^<]*</(?:\w+:)?\1> 

die regex demo nachschauen. Beachten Sie, dass die (?:\w+:)? willkürlichen Namespace in den offenen und schließenden Tag-Knoten übereinstimmt. [^<] passt auf ein beliebiges Zeichen außer <, so dass es nicht zum nächsten Knoten überläuft.

+0

Um die Frage ist speziell über Regex ... immer noch dieser Ansatz ist so viel besser geeignet für den Job muss ich es trotzdem +1 geben :) – grek40

+0

@wiktor nur eine kurze Frage ,? leistungs weise was ist die beste option? Linq/Regex/Xpath. da ich einen riesigen Satz von XML-Dateien behandle, um den Text zu durchsuchen –

+0

Wenn Sie mit gültigen XML-Dateien umgehen, würde ich lieber einen XML-Parser mit LINQ verwenden. Wenn Sie mit XML-Dateien arbeiten müssen, die gültig oder ungültig sein können, kann Regex helfen und die Geschwindigkeit hängt vom Inhalt, der XML-Größe und dem Glück ab. Hinweis Ich muss jeden Tag mit ungültigem XML arbeiten und verwende Regex mit XML - aber es ist kein reguläres XML, sondern ein TMX-Dateiformat, und ich habe einen speziellen Parser, der für sie manuell erstellt wird. Und die Leistung ist in Ordnung. –

1

Sie suchen nach der genauen Übereinstimmung der Zeichenfolge "sample" innerhalb eines Tags, nicht der Zeichenfolge, die "sample" als Teilstring enthält. Sie können Ihren Ausdruck beheben, wie alle folgenden Zeilen zu erhalten:

<([\w]+)[^>]*>[a-zA-Z ]*sample[a-zA-Z ]*<\/\1> 
+1

Ich würde lieber '[^ <]' anstelle der '[a-zA-Z]' Platzhalter verwenden ... oder einfach nicht gierig alles akzeptieren. Das ist nur eine Lösung für die gegebenen Beispiele. Mit beliebigem XML wird jeder Regex irgendwo fehlschlagen. – grek40

+0

Sobald eine Ziffer oder ein Interpunktionszeichen vor 'sample' steht, wird keine Übereinstimmung mit' [a-zA-Z] * 'gefunden. –

+0

Ich stimme dir zu, es deckt natürlich nicht alle Fälle ab - zum Beispiel könnte es auch Interpunktionssymbole geben usw. - aber es gibt eine Idee, wo das Problem ist und wie bestimmte Eingaben in einer Frage behandelt werden können. –

Verwandte Themen