2017-04-20 4 views
1

hier durch andere Frage Inspired (Ich nahm bereits eine nicht-regex Lösung) c# regex match set of characters in any order only onceC# regex eine Gruppe von Zeichen übereinstimmen, die nicht repeates

Aber diese Lösung aus @Dmitry Egorov ist bei weitem elegantere und ich bin immer noch kämpfen, um es richtig zu lösen (wenn es mit einer regex gelöst werden kann) Der nächstgelegene ich bekommen, ist dies ein

^(.|\n)*<\[SG (?!.*(.).*\2)[msbrelft]+\]>(.|\n)*$ 

Der Text sollte ist passen als

ID-CFI Location 02h displays sector protection status for the sector selected by the sector address (SA) used in the ID-CFI enter 
command. To read the protection status of more than one sector it is necessary to exit the ID ASO and enter the ID ASO using the 
new SA. <[SG sbl]> 
Page mode read between ID locations other than 02h is supported. 
folgt

ich in C# verwenden diese Prüfung

if (!Regex.IsMatch(obj.Object_Text, format.Value)) 
... 
... 

In Worten sollte diese Begegnung:

- if this exists anywhere in text <[SG sbl]> including over \n or \r\n 
- letters should be in this group of letters [msbrelft] 
- must be minimum one letter, eg. <[SG s]> 
- can be up to all from group, eg. <[SG sbl]> 
- must be only one letter (no duplicates), eg. <[SG sbsl]> is NOT good 

Ich will nicht Gruppe extrahieren, validieren nur den gesamten Text, wenn < [SG xx enthalten. .]> mit vorher erklärten Regeln.

Nun, was ich schon kommen und fuhr mich verrückt, war

^(.|\n)*<\[SG (?!.*(.).*\2)[msbrelft]+\]>(.|\n)*$ 

die Validierung nicht, ob nach meiner interessanten Gruppe gibt es zwei Buchstaben auf der gleichen Linie (keine \ r \ n oder \ n).

So zum Beispiel das funktioniert (es gibt ein \ n oder \ r \ n nach Gruppe)

ID-CFI Location 02h displays sector protection status for the sector selected by the sector address (SA) used in the ID-CFI enter 
command. To read the protection status of more than one sector it is necessary to exit the ID ASO and enter the ID ASO using the 
new SA. <[SG sbl]> 
Page mode read between ID locations other than 02h is supported. 

und dies nicht (zwei Räume nach meiner Gruppe)

ID-CFI Location 02h displays sector protection status for the sector selected by the sector address (SA) used in the ID-CFI enter 
command. To read the protection status of more than one sector it is necessary to exit the ID ASO and enter the ID ASO using the 
new SA. <[SG sbl]> Page mode read between ID locations other than 02h is supported. 

Jede Hilfe wird sehr geschätzt werden! Danke.

+0

Suchen Sie gültig '' Strings? Wie [diese] (http://regexstorm.net/tester?p=%3c%5c%5bSG%5cs%2b%28%3f!%5bmsbrelft%5d*%28%5bmsbrelft%5d%29%5bmsbrelft%5d* % 5c1% 29% 5bmsbrelft% 5d% 2b% 5d% 3e & i =% 3c% 5bSG + sbl% 5d% 3e% 0d% 0a.% 3c% 5bSG + sbsl% 5d% 3e)? –

+0

Der beste Weg mit Regex ist es, die Regex-Ergebnisse zu erhalten. Verwenden Sie dann Distinct-Methode für Regex-Ergebnisse. Wenn keine Duplikate vorhanden sind, werden die Regex-Ergebnisse und die Distinct-Ergebnisse übereinstimmen. – jdweng

Antwort

1

Als erstes, wenn Sie nur eine <SG xxx> mit Ihren Regeln finden möchten, um die Zeichenfolge zu validieren, müssen Sie die vollständige Zeichenfolge in Ihrem Muster nicht beschreiben.

Das Problem mit dem Muster ist, dass Ihre negativen Look-Ahead-Zeichen außerhalb der eckigen Klammern begrenzt Teilzeichenfolge, überprüfen Sie das Problem den Punkt ändern, mit einem negativen Charakterklasse müssen zu vermeiden, dass die eckige Klammer umfasst nicht:

<\[SG (?![^\]]*([^\]])[^\]]*\1)[msbrelft]+\]> 

Sie können es auch so schreiben:

<\[SG (?:([msbrelft])(?![^\]]*?\1))+\]> 
+1

danke, mein Herr! Perfekt! Es nervt mich von gestern, vielen Dank. – orfruit

1

Ersetzen der (.|\n)* von [\S\s]* scheint zu funktionieren.
\ S: alles, was kein Leerzeichen
\ s ist: Leerzeichen, Tabulatoren, Zeilenvorschübe, ...

^[\S\s]*<\[SG (?!\w*(\w)\w*\1)[beflmrst]+\]>[\S\s]*$ 

Auch die negative Vorschau, verwendet die Duplikate zu vermeiden jetzt \w, statt ..
Da ] kein Wortzeichen ist, wird nicht darüber hinaus gesucht.
\ w: Wortzeichen.

^.*<\[SG (?!\w*(\w)\w*\1)[beflmrst]+\]>.*$ 

Wie auch immer, ich bemerkte, von der anderen Antwort, dass man wirklich nur für die SG suchen wollte:

Oder wie Wiktor wies darauf hin, übergeben RegexOptions.Singleline an den Regex-Konstruktor und der Regex kann golfcoded werden Tag, anstatt den gesamten Text zu erhalten, wenn er das Tag enthält.

Also am Ende, dies zu tun:

<\[SG (?!\w*(\w)\w*\1)[beflmrst]+\]> 
+2

Keine Notwendigkeit, '[\ s \ S]' in C# zu verwenden, können Sie "RegexOptions.Single" Flag an den Regex-Konstruktor übergeben und "." Wird jedes Zeichen entsprechen. '. *' ist dann genug. –

+0

Danke für die Mühe! – orfruit

+0

@ WiktorStribiżew Danke für den Hinweis :) – LukStorms

Verwandte Themen