Regex, wie man ein optionales Zeichen findet

147

Ich habe eine Regex, von der ich dachte, dass sie bis jetzt richtig funktioniert. Ich muss einen optionalen Charakter finden. Es kann da sein oder nicht.

Hier sind zwei Zeichenfolgen. Die obere Zeichenfolge stimmt überein, die untere nicht. Das Fehlen eines einzelnen Buchstabens in der unteren Zeichenfolge führt zum Fehlschlagen.

Ich möchte den einzelnen Buchstaben nach den ersten 5 Ziffern erhalten, wenn er vorhanden ist, und wenn nicht, den Rest der Zeichenfolge weiter abrufen. Dieser Brief kann sein A-Z.

Wenn ich ([A-Z]{1}) +.*? +aus der Regex entferne, passt es zu allem, was ich brauche, außer dem Buchstaben, aber es ist irgendwie wichtig.

20000      K               Q511195DREWBT            E00078748521
30000                      K601220PLOPOH            Z00054878524

Hier ist der reguläre Ausdruck, den ich verwende.

/^([0-9]{5})+.*? ([A-Z]{1}) +.*? +([A-Z]{1})([0-9]{3})([0-9]{3})([A-Z]{3})([A-Z]{3}) +([A-Z])[0-9]{3}([0-9]{4})([0-9]{2})([0-9]{2})/
Jim
quelle

Antworten:

246

Verwenden

[A-Z]?

um den Brief optional zu machen. {1}ist redundant. (Natürlich könnte man auch schreiben, [A-Z]{0,1}was dasselbe bedeuten würde, aber dafür ?ist das da.)

Sie könnten Ihre Regex verbessern

^([0-9]{5})+\s+([A-Z]?)\s+([A-Z])([0-9]{3})([0-9]{3})([A-Z]{3})([A-Z]{3})\s+([A-Z])[0-9]{3}([0-9]{4})([0-9]{2})([0-9]{2})

Und da in den meisten Regex-Dialekten \ddasselbe ist wie [0-9]:

^(\d{5})+\s+([A-Z]?)\s+([A-Z])(\d{3})(\d{3})([A-Z]{3})([A-Z]{3})\s+([A-Z])\d{3}(\d{4})(\d{2})(\d{2})

Aber: Brauchen Sie wirklich 11 separate Erfassungsgruppen? Und wenn ja, warum erfassen Sie nicht die vorletzte Zifferngruppe?

Tim Pietzcker
quelle
Tim, ich bin mir ehrlich gesagt nicht sicher, da ich diesen regulären Ausdruck nicht geschrieben habe. Ich bin noch ziemlich neu in Regex. Wenn Sie eine bessere Schreibweise sehen, bin ich offen für Vorschläge.
Jim
1
Tim, dein Beispiel funktioniert für beide Zeichenfolgen, unabhängig davon, ob ich einen Buchstaben an dieser Position habe oder nicht. Vielen Dank.
Jim
26

Sie können den einzelnen Buchstaben optional machen, indem Sie ein Nachher hinzufügen ?als:

([A-Z]{1}?)

Der Quantifizierer {1}ist redundant, sodass Sie ihn löschen können.

Codaddict
quelle
Danke codeaddict. Tritt das Fragezeichen an die Stelle des `+. *? + `?
Jim
Wenn Sie grep regex verwenden, wird eine Fehlermeldung angezeigt, wenn Sie die {1} löschen (grep: lookbehind assertion hat keine feste Länge). Das ist also ein
Zunderscore
6

Sie müssen den einzelnen Buchstaben auch als optional markieren:

([A-Z]{1})? +.*? +

oder machen Sie das ganze Teil optional

(([A-Z]{1}) +.*? +)?
Stefan
quelle
1
Stefan, ich möchte den Brief ganz optional machen. Ich habe beide ausprobiert, aber es passt immer noch zu nichts. Ich bin sicher, dass ich es falsch verstanden habe. Könnten Sie Ihr Beispiel ändern, um es in die Zeichenfolge aufzunehmen?
Jim
0

Sie können auch einen einfacheren Regex verwenden, der für Ihren Fall entwickelt wurde, z. B. (.*)\/(([^\?\n\r])*)wo $2Sie möchten.

robinvrd
quelle