C # expresie regulată pentru a se potrivi acestor șiruri de caractere

Am niște șiruri de caractere cu următorul format:

--> ABCDEF_(0) "Abcde fgh"

--> GHIJ4 1

Primul ar trebui să returneze 3 meciuri:

-->
ABCDEF_(0)
"Abcde fgh"

Cel de-al doilea ar trebui să returneze, de asemenea, 3 meciuri:

-->
GHIJ4
1

Deci, ceea ce vreau să se potrivească este:

  1. The arrow (-->)
  2. Groups of non-whitespace, non-quote-surrounded characters
  3. Expressions enclosed in quotes including their whitespace

S-ar putea presupune mai multe grupuri de tip (2) și (3) într-un șir, deci un singur șir ar putea avea mai mult de 3 meciuri.

Până acum, asta este ceea ce am:

  var regex = new Regex(
      @"-->" +//match the starting arrow
      @"|[^""\s]*\S+[^""\s]*" +//match elements not surrounded by quotes, trimmed of surrounding whitespace
      @"|""[^""]+""");//match elements surrounded by quotes

Dar acest lucru nu funcționează deoarece rupe expresiile în citate, întorcându-se pentru primul șir:

-->
ABCDEF_(0)
"Abcde
fgh"

Ce expresie regulată ar funcționa? Dacă există o metodă mai simplă decât expresiile regulate, aș accepta și ea.

0
@KazR Partea a treia a exemplului 2 se presupune că se potrivește și este acoperită de criteriul # 2. Criteriul # 3 este doar pentru articolele învecinate, cum ar fi cea de-a treia parte a primului exemplu.
adăugat autor Asik, sursa
Partea a treia (1) a celui de-al doilea exemplu nu are dublu-ghilimele în jurul său, este că încă ar trebui să se potrivească? În caz afirmativ, articolul 3 din lista criticii trebuie modificat.
adăugat autor KazR, sursa

2 răspunsuri

Datorită unui răspuns care a fost șters rapid din anumite motive, am reușit să rezolv problema.

idei:

  • The first group "-->" is redundant
  • Second and third group should be swapped.

Rezultat regex:

Regex sWordMatch = new Regex(
      @"""[^""]*""" +//groups of characters enclosed in quotes
      @"|[^""\s]*\S+[^""\s]*",//groups of characters without whitespace not enclosed in quotes
0
adăugat

Ar fi mai ușor să folosiți capturile (am folosit capturile numite aici):

var regex = new Regex(@"-->"//match the arrow
    + @"\s+(?[^\s]+)"//capture the first part always unquoted
    + @"(\s+(?(""[^""]+"")|[^\s]+))+");//capture the second part, possibly quoted

var match = regex.Match("--> ABCDEF_(0) \"Abcde fgh\"");
Console.WriteLine(match.Groups["first"].Value);
Console.WriteLine(match.Groups["second"].Value);

match = regex.Match("--> GHIJ4 1");
Console.WriteLine(match.Groups["first"].Value);
Console.WriteLine(match.Groups["second"].Value);

match = regex.Match("--> GHIJ4 1 \"Test Something\" \"Another String With Spaces\" \"And yet another one\"");
Console.WriteLine(match.Groups["first"].Value);
Console.WriteLine("Total matches:" + match.Groups["second"].Captures.Count);
Console.WriteLine(match.Groups["second"].Captures[0].Value);
Console.WriteLine(match.Groups["second"].Captures[1].Value);
Console.WriteLine(match.Groups["second"].Captures[2].Value);
Console.WriteLine(match.Groups["second"].Captures[3].Value);
0
adăugat
Acest lucru este interesant, dar poate exista un număr arbitrar de meciuri pe linie, nu neapărat 3. Un șir ar putea fi, de exemplu, "-> ABCDFEF 1" și rer43 "3". N-am specificat-o, îmi pare rău, voi adăuga la post.
adăugat autor Asik, sursa
Se pare că ar funcționa, dar ar fi oarecum neînsemnat. Tot ce vreau este colecția de potriviri pe care o convertesc la o listă de șiruri de caractere și să trimit la altă metodă, așa că trebuie să treci prin fiecare grup este un pic de hassle. Am reușit să răspund și la întrebarea mea. Cu toate acestea, nu am fost conștient de tehnica, așa că mulțumesc și am invocat-o. :)
adăugat autor Asik, sursa
Exemplu actualizat pentru a răspunde mai multor meciuri ale celui de-al doilea grup
adăugat autor Martin Ernst, sursa