2016-08-12 6 views
1

Ich versuche, Regex zu schreiben, aber in einigen Fällen funktioniert es nicht. Hier ist die regexRegex Matching kürzeste Übereinstimmung statt längste

(\/[ABCGIKLNPRSUV])?(\/RC-[A-Z0-9]{2,6})? 

Die Spiele eine der folgenden sein könnte

  • /R/RC-ABC123
  • /R
  • /RC-ABC123

Die über Regex funktioniert für/R und/R/RC-ABC123 aber nicht/RC-ABC123. Für/RC-ABC123 wird der Vergleich mit der ersten Gruppe und nicht mit der zweiten Gruppe durchgeführt und nur/R als übereinstimmende Komponente verwendet.

Wie kann ich es für alle Fälle funktionieren lassen. Außerdem ist der obige Ausdruck nur ein Teil des vollständigen Ausdrucks, d. H. Es könnte eine andere (dritte) Gruppe nach RC-ABC123 geben. Aber ich möchte zuerst für diese 2 Gruppen arbeiten.

Aktualisieren Das ?? scheint in regex101 zu funktionieren, aber nicht in Java. Ich erhalte 2 Gruppen, aber mit Null-Werten für/R/RC-ABC123 mit dem folgenden Code

Pattern pattern = Pattern.compile("(/[A-Z])??(/RC-[A-Z0-9]{2,6})?"); 
    Matcher matcher = pattern.matcher("/R/RC-ABC12345"); 
    if(matcher.find()) { 
     for(int i=1; i<= matcher.groupCount(); i++) { 
      System.out.println("Group("+i+") = " + matcher.group(i)); 
     } 
    }else { 
     System.out.println("Pattern does not match"); 
    } 
+1

FYI nur, paßt es die erste optionale Gruppe, so dass es an dieser Stelle getan hat. Haben Sie versucht, die Anker '^' und '$' einzufügen, damit * ein vollständiger Eintrag gefunden werden muss? – usr2564301

+0

Probieren Sie ['(/R(?:C-[A-Z0-9]{2,6})?)(()%BCGIKLNPSUV])">(https://regex101.com/r/xA9fA2/1). Hinweis in Java regex, Sie müssen nicht '/' entkommen. –

+0

Sie können ein optionales Element nicht gierig machen, indem Sie '' 'anstelle von' ' – Barmar

Antwort

0

die erste optionale Gruppe mit ?? nicht gierig machen, so wird es vorziehen, die zweite Gruppe zu passen, wenn es ein hat Wahl.

(/[ABCGIKLNPRSUV])??(/RC-[A-Z0-9]{2,6})? 

DEMO

+0

Danke..aber sieht aus wie du bist Verwenden der Option/g. Wenn Sie die Option/g entfernen, funktioniert sie nicht. Wenn ich etwas wie Java verwende, glaube ich nicht, dass es eine Option gibt, um/g anzugeben. Außerdem rufe ich eine Bibliothek auf, die von jemandem geschrieben wurde, der nur das Muster und die Zeichenfolge, die abgeglichen werden sollen, aufnimmt und die Gruppen ausspuckt. – delta313

+0

Der Modifizierer 'g' wird in regex101.com benötigt, um mehrere Übereinstimmungen in der Demo zu sehen. Sie brauchen es nicht, wenn Sie nur jeweils eine Saite abgleichen. – Barmar

+0

Nun, es funktioniert nicht in Java, da ich 2 Gruppen aber mit Nullwerten bekomme. Basierend auf dem Ergebnis von regex101, akzeptiere ich die Antwort. – delta313

0

Sie müssen sicherstellen, dass die R von der ersten optionalen Gruppe Zeichenklasse genommen, da es das erste Gruppenspiel an der gleichen Stelle wie die zweite Gruppe ermöglicht.

Sie innerhalb der ersten Erfassungsgruppe eine Nicht-Erfassung Untergruppe erstellen kann mit dieser Situation zu umgehen und „Temperament“ den R Zweig mit einem negativen Look-Ahead, so dass es nur R s abgestimmt, die nicht mit C- gefolgt sind und dann 2 bis 6 Großbuchstaben ASCII-Buchstaben oder Ziffern:

Pattern pattern = Pattern.compile("(/(?:R(?!C-[A-Z0-9]{2,6})|[ABCGIKLNPSUV]))?(/RC-[A-Z0-9]{2,6})?"); 

Siehe Java demo.Testergebnisse:

/RC-ABC123 -> { Group(1) = null, Group(2) = /RC-ABC123 } 
/R/RC-ABC123 -> { Group(1) = /R, Group(2) = /RC-ABC123 } 
/R   -> { Group(1) = /R, Group(2) = null } 
/S/RC-ABC123 -> { Group(1) = /S, Group(2) = /RC-ABC123 } 

Muster Details:

  • (/(?:R(?!C-[A-Z0-9]{2,6})|[ABCGIKLNPSUV]))? - Optional Gruppe 2:
    • / - ein Schrägstrich
    • (?:R(?!C-[A-Z0-9]{2,6})|[ABCGIKLNPSUV])-2 Alternativen in einer Nicht-Erfassung Gruppe :
      • R(?!C-[A-Z0-9]{2,6})-R, die mit C- und dann 2 bis 6 Großbuchstaben ASCII-Buchstaben oder Ziffern
      • | nicht gefolgt ist - oder
      • [ABCGIKLNPSUV]-1 dieser Briefe
  • (/RC-[A-Z0-9]{2,6})? - Optional Gruppe 2 :
    • /RC- - wörtliche Teilzeichenfolge /RC-
    • [A-Z0-9]{2,6} - 2 bis 6 ASCII-Groß- und Kleinbuchstaben.