2012-04-05 9 views
2

Dies ist eine Fortsetzung meiner vorherigen Frage .NET regex engine returns no matches but I am expecting 8.Match regex Muster, wenn nicht innerhalb einer Reihe von Anführungszeichen (Text erstreckt sich über mehrere Zeilen)

Meine Anfrage verarbeitet alles perfekt und ich habe meine Capture-Gruppen arbeiten gut, aber ich habe einen Rand Fall, den ich nicht wissen, wie man damit umgehen.

Here is a test case, mit denen ich Probleme habe.

INSERT INTO [Example] ([CaseNumber] , [TestText]) 
VALUES 
(1 , 'Single Line Case'), 
(2 , 'Multi 
Line Case'); 
(3 , 'Two Lines with odd end ''); 
Case'); 
(4 , ''), 
(5 , 'Case 3 is the Empty Text Case'); 

Hier ist mein Muster ich verwende, benutze ich die RegexOptions Flaggen Singleline, Multiline, ExplicitCapture und IgnorePatternWhitespace

^\(
((('(?<s>.*?)'(?!')) | 
(?<n>-?[\d\.]+) 
)(\s,\s)? 
)+ 
#(?<!'') #Commented Case 3 works, un-commented case 2 works 
\)[;,]\r?$ 

kann ich entweder handhaben Fall 3 oder Fall 4, aber ich habe Probleme beim Umgang beide.

Wenn ich eine Möglichkeit hatte zu überprüfen, ob es eine gerade Anzahl von ' in der Erfassungsgruppe gibt, dann könnte ich prüfen, ob wir uns an einem echten Zeilenende oder in einem Textblock befinden, der a hat Die Zeile, die endet, passt zufällig zum Muster. aber ich kann nicht herausfinden, wie man other examples ändert, um mehrfach linierte Textfolgen zu behandeln.

Kann was ich will mit einer einzigen Regex-Abfrage getan werden oder bin ich gezwungen, Nachbearbeitung zu tun (unter Verwendung der kommentierten Fall) und tun dies zwei Pässe?


Hier ist der Code es in LINQPad zu laufen

string text = 
@"INSERT INTO [Example] ([CaseNumber] , [TestText]) 
VALUES 
(1 , 'Single Line Case'), 
(2 , 'Multi 
Line Case'); 
(3 , 'Two Lines with odd end ''); 
Case'); 
(4 , ''), 
(5 , 'Case 3 is the Empty Text Case'); 
"; 

const string recordRegex = 
@"^\(
((('(?<s>.*?)'(?!')) | 
(?<n>-?[\d\.]+) 
)(\s,\s)? 
)+ 
#(?<!'') #Commented Case 3 works, un-commented case 2 works 
\)[;,]\r?$"; 

var records = Regex.Matches(text, recordRegex, RegexOptions.Singleline | RegexOptions.Multiline | RegexOptions.IgnorePatternWhitespace | RegexOptions.ExplicitCapture); 
records.Dump(); 
+0

Was ist die zitierte Syntax hier? Ich sehe nicht, wie "foo" gültig ist. – Qtax

+0

@Qtax Sie haben Recht, aber ''foo' '\ r \ nbar'' ist gültig. –

+0

Ah ja, ich habe die folgende Zeile nicht besonders angeschaut, Syntax-Hervorhebung hat mich getäuscht. – Qtax

Antwort

1

Ein Ausdruck wie diese solche Zitate passen würde:

(?:'[^']*')+ 

Wenn Sie foo übereinstimmen soll, wenn es nicht Innerhalb solcher Anführungszeichen könnten Sie etwas verwenden wie:

foo(?=[^']*(?:'[^']*'[^']*)+\z) 

ein Spiel pro Zeile mit dem nicht notierte Text und Zahlen als Einfanggruppen

Etwas wie folgt aus:

(?xm)^ 
\(

(?: 
    (?: 
     (?<quote> (?:'[^']*')+) 
    | (?<num> -?\d+(?:\.\d+)?) 
    | (?<x>  X'[0-9a-f]*') 
    ) 
    (?:\s*,\s*)? 
)+ 

\) 
[;,] 
\r?$ 
+0

Ich habe meine letzte Zeile meines Musters in '\) [;,] (? = [^ '] * (?:' [^ '] *' [^ '] *) + \ Z) \ r? $' Geändert . Es stimmt jetzt mit 3 & 4 überein, aber es kann jetzt nicht mehr 5 erfassen. –

+0

@ScottChamberlain, ich verstehe die Frage nicht ganz, was willst du, dass dieser Ausdruck das tut? – Qtax

+0

Folge dem Link, den ich in meiner Frage an die Regex-Heldenseite geschrieben habe, er sollte eine Übereinstimmung pro Zeile mit dem nicht aufgeführten Text und Zahlen als Erfassungsgruppen haben. –

Verwandte Themen