2016-09-02 2 views
5

Ich habe eine Regex, die mit dem Datumsformat mit Komma übereinstimmt.Regex-Option "Multiline"

yyyy/mm/dd oder yyyy/mm

Zum Beispiel:

2016/09/02,2016/08,2016/09/30

Mein Code:

string data="21535300/11/11\n"; 
Regex reg = new Regex(@"^(20\d{2}/(0[1-9]|1[012])(/(0[1-9]|[12]\d|30|31))?,?)*$", 
         RegexOptions.Multiline); 

if (!reg.IsMatch(data)) 
    "Error".Dump(); 
else 
    "True".Dump(); 

Ich benutze die Option multiline. Wenn Zeichenfolge Daten "\ n" haben. Jedes Zeichen entspricht dieser Regex.

Zum Beispiel:

string data="test\n" 
string data="2100/1/1" 

I find option definition in MSDN. Es sagt:

Es ändert die Interpretation der^und $ Sprachelemente, so dass sie den Anfang und das Ende einer Zeile anstelle von Anfang und Ende der Eingabezeichenfolge übereinstimmen.

Ich habe nicht verstanden, warum dieses Problem passiert ist. Jeder kann es erklären? Danke.

+1

Möglicherweise, weil Ihre Regex eine Gruppe ist 0 oder mehr – Kelvin

+0

Ja, die Regex entspricht einer leeren * Zeile *. –

+0

Danke. Ich verstehe bald nach Ihrer Erklärung. –

Antwort

2

Ihre Regex kann mit einer leeren Zeile übereinstimmen, die Sie erhalten, sobald Sie am Ende der Zeichenfolge einen Zeilenumbruch hinzugefügt haben. "test\n" enthält 2 Zeilen, und die zweite wird abgeglichen.

Ihre RegexMuster in einem Modus freiAbstand:

^     # Matches the start of a line 
(    # Start of Group 1 
    20\d{2}/ 
    (0[1-9]|1[012]) 
    (/ 
    (0[1-9]|[12]\d|30|31) 
    )?,? 
)*    # End of group 1 - * quantifier makes it match 0+ times 
$     # End of line 

Wenn Sie nicht möchten, dass es eine leere Zeile passen, die letzten )* mit )+ ersetzen.

Eine Alternative ist ein abgerollt Muster wie

^20\d{2}/(0[1-9]|1[012])(/(0[1-9]|[12]\d|3[01]))?(,20\d{2}/(0[1-9]|1[012])(/(0[1-9]|[12]\d|3[01]))?)*$ 

die regex demo Siehe zu verwenden. Im Inneren des Code ist es ratsam, einen Block und bauen das Muster dynamisch zu verwenden:

string date = @"20\d{2}/(0[1-9]|1[012])(/(0[1-9]|[12]\d|3[01]))?"; 
Regex reg = new Regex(string.Format("^{0}(,{0})*$", date), RegexOptions.Multiline); 

Wie Sie, den ersten Block (nach dem Start der Linie ^ Anker) sehen kann, ist obligatorisch hier, und damit Eine leere Zeile wird niemals abgeglichen.