Domanda

Ho la stringa come questa:

String s = "word=PS1,p1,p2,p3=q1,q2|word2=PS3,p4,p5,p6=q3";

o come questo:

String s2 = "word3=PS2,p7,p8=q4,q5,q6|=PS3,p9=";

o come questo:

String s3 = "=PS3=";

Quindi, in formale - stringa contiene alcune definizioni di parole nel dizionario, suddivise da "|" simbolo.

qui:

  • parola - parola nel dizionario (opzionale, come in s2 o s3)

  • PS1, PS2, PS3 - Parte del tag vocale (richiesto)

  • P1, P2, ... - Alcuni parametri (opzionale)

  • Q1, Q2, Q3, ... - Alcuni altri parametri (anche opzionali)

Voglio costruire Regex, che trova tutte le occorrenze di tali stringhe nel testo e mi dà i gruppi:

  • Gruppo1 - parola
  • Group2 - Parte del tag vocale
  • Group3, Group4, ... - Parametri P
  • Gruppo (K), Gruppo (K+1), ... - un altro parametri (Q)

Non mi interessa l'indice del gruppo dell'ultimo parametro P e il primo parametro Q. Dovrei sapere che il primo gruppo - è parola (può essere nullo), secondo gruppo - parte del discorso e altri gruppi - parametri P e Q.

Ora ho un tale regex:

"([a-z]*)?=([A-Z]+)(,?[a-z]+)*=(,?[a-z]+)*")

Ma non funziona correttamente. Mi mostra solo gli ultimi parametri p e q. IE (per S2):

  • Gruppo1 = Word3 - OK
  • Gruppo2 = PS2 - OK
  • Gruppo3 = P8 - Not OK (solo ultimo parametro p)
  • Gruppo4 = Q6 - Not OK (anche l'ultimo parametro Q)

Potresti aiutarmi?

AGGIORNARE: "="-Carattere solo il carattere diviso tra P-parametri e parametri Q. Non è necessario nel mio problema. Dovresti pensare che i parametri P e i parametri Q non sono diversi.

Esempio di input reale:

String s = "bread=NOUN,plur,link=form|=VERB="
È stato utile?

Soluzione

Non è possibile avere un numero variabile di gruppi di acquisizione in Regex. In .NET potresti avere più catture per ciascun gruppo, ma non in Java. Il problema per te è che il motore Regex memorizza solo l'ultima partita di successo per ciascun gruppo. Il meglio che potresti fare è abbinare tutti i parametri P e Q in due grandi gruppi, quindi dividerli.

Pattern pattern1 = Pattern.compile(
    "([^|=,]*)" +                // Group 1: The word. Zero or more characters.
    "=([^|=,]*)" +               // Group 2: The part of speech.
    ",?([^|=,]*(?:,[^|=,]*)*)" + // Group 3: The p-params
    "=([^|=,]*(?:,[^|=,]*)*)"    // Group 4: The q-params
);
Matcher matcher = pattern1.matcher("word=PS1,p1,p2,p3=q1,q2|word2=PS3,p4,p5,p6=q3");
while (matcher.find()) {
  String word = matcher.group(1);
  String partOfSpeech = matcher.group(2);
  String pParamString = matcher.group(3);
  String qParamString = matcher.group(4);
  String[] pParams = pParamString.split(",");
  String[] qParams = qParamString.split(",");
  // Do something with the above variables...
}

ero solito [^|=,]* per abbinare qualsiasi carattere non speciale.

Altri suggerimenti

Quando ho problemi del genere guardo ai modificatori sui quantificatori. Potresti voler che alcuni dei quantificatori vengano modificati per essere avidi, ad esempio

(,? [az]+)+*

Questa differenza, sopra, è che lo zero finale o più quantificatore ora afferra il più possibile. Questo è solo un esempio e non sono affatto sicuro che quel particolare modificatore sia ciò di cui hai bisogno ma, dato che la tua espressione funziona come hai riferito, sembra probabile che questi modificatori lo ottengano per il resto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top