it-swarm.com.de

Wie man einen Regex-Ausdruck durchläuft

Nehmen wir an, ich habe den folgenden String:

name1=gil;name2=orit;

Ich möchte alle Übereinstimmungen von name=value finden und sicherstellen, dass die gesamte Zeichenfolge dem Muster entspricht.

Also habe ich folgendes gemacht:

  1. Stellen Sie sicher, dass das gesamte Muster Ihren Wünschen entspricht.

    Pattern p = Pattern.compile("^((\\w+)=(\\w+);)*$");
    Matcher m = p.matcher(line);
    if (!m.matches()) {
        return false;
    }
    
  2. Iteriere über das Muster name=value

    Pattern p = Pattern.compile("(\\w+)=(\\w+);");
    Matcher m = p.matcher(line);
    while (m.find()) {
        map.put(m.group(1), m.group(2));
    }
    

Gibt es eine Möglichkeit, dies mit einer Regex zu tun?

24
gilsilas

Sie können Übereinstimmungen mit einem regulären Ausdruck überprüfen und iterieren, indem Sie:

  • Stellen Sie sicher, dass zwischen Übereinstimmungen (z. B. name1=x;;name2=y;) keine nicht übereinstimmenden Zeichen vorhanden sind, indem Sie am Anfang unseres Regex einen \G setzen. Dies bedeutet "das Ende der vorherigen Übereinstimmung" .

  • Um zu prüfen, ob wir das Ende der Zeichenfolge bei unserem letzten Treffer erreicht haben, vergleichen Sie die Länge unserer Zeichenfolge mit Matcher.end() , wodurch der Versatz nach dem letzten übereinstimmenden Zeichen zurückgegeben wird.

So etwas wie:

String line = "name1=gil;name2=orit;";
Pattern p = Pattern.compile("\\G(\\w+)=(\\w+);");
Matcher m = p.matcher(line);
int lastMatchPos = 0;
while (m.find()) {
   System.out.println(m.group(1));
   System.out.println(m.group(2));
   lastMatchPos = m.end();
}
if (lastMatchPos != line.length())
   System.out.println("Invalid string!");

Live Demo .


In einigen Sprachen können Sie die einzelnen Übereinstimmungen direkt über iterieren
^((\\w+)=(\\w+);)*$, aber ich glaube nicht, dass Sie dies in Java tun können.

29
Dukeling

Sie müssen den Multiline-Modus aktivieren, damit "^" und "$" wie erwartet funktionieren.

Pattern p = Pattern.compile("^(?:(\\w+)=(\\w+);)*$", Pattern.MULTILINE);
while (m.find()) {
    for (int i = 0; i < m.groupCount() - 2; i += 2) {
        map.put(m.group(i + 1), m.group(i + 2));
    }
}

Wenn richtig, müssen Sie noch durch übereinstimmende Gruppen für jede Zeile iterieren und aus der äußeren Gruppe eine nicht erfassende Gruppe (?:...) machen.

3
weaselflink
String example = "name1=gil;name2=orit;";
Pattern pattern = Pattern.compile("((name[0-9]+?=(.+?);))+?");
Matcher matcher = pattern.matcher(example);
// verifies full match
if (matcher.matches()) {
    System.out.println("Whole String matched: " + matcher.group());
    // resets matcher
    matcher.reset();
    // iterates over found
    while (matcher.find()) {
        System.out.println("\tFound: " + matcher.group(2));
        System.out.println("\t--> name is: " + matcher.group(3));
    }
}

Ausgabe: 

Whole String matched: name1=gil;name2=orit;
    Found: name1=gil;
    --> name is: gil
    Found: name2=orit;
    --> name is: orit
0
Mena