Regex comment faire correspondre un caractère facultatif

147

J'ai une expression régulière qui, à mon avis, fonctionnait correctement jusqu'à présent. J'ai besoin de faire correspondre un caractère facultatif. Cela peut être là ou non.

Voici deux chaînes. La chaîne du haut correspond alors que la chaîne du bas ne l'est pas. L'absence d'une seule lettre dans la chaîne inférieure est ce qui le fait échouer.

J'aimerais obtenir la lettre unique après les 5 chiffres de départ si elle est là et sinon, continuer à obtenir le reste de la chaîne. Cette lettre peut être A-Z.

Si je supprime ([A-Z]{1}) +.*? +de l'expression régulière, cela correspondra à tout ce dont j'ai besoin sauf la lettre, mais c'est assez important.

20000      K               Q511195DREWBT            E00078748521
30000                      K601220PLOPOH            Z00054878524

Voici le regex que j'utilise.

/^([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
la source

Réponses:

247

Utilisation

[A-Z]?

pour rendre la lettre facultative. {1}est redondant. (Bien sûr, vous pouvez également écrire [A-Z]{0,1}ce qui signifierait la même chose, mais c'est à cela que ?sert.)

Vous pouvez améliorer votre regex pour

^([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})

Et, puisque dans la plupart des dialectes regex, \dest le même que [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})

Mais: avez-vous vraiment besoin de 11 groupes de capture séparés? Et si oui, pourquoi ne pas capturer le quatrième au dernier groupe de chiffres?

Tim Pietzcker
la source
Tim, honnêtement, je ne suis pas sûr car je n'ai pas écrit cette expression régulière. Je suis encore assez nouveau pour regex. Si vous voyez une meilleure façon d'écrire ceci, je suis ouvert aux suggestions.
jim
1
Tim, votre exemple fonctionne pour les deux chaînes, que j'aie une lettre à cette position ou non. Merci.
jim
26

Vous pouvez rendre la lettre unique facultative en ajoutant un ?après elle comme suit:

([A-Z]{1}?)

Le quantificateur {1}est redondant, vous pouvez donc le supprimer.

codaddict
la source
Merci codeaddict. Le point d'interrogation remplace-t-il le `+. *? + `?
jim
Lorsque vous utilisez grep regex, vous obtiendrez une erreur si vous supprimez {1} (l'assertion grep: lookbehind n'est pas de longueur fixe). C'est donc un cas pour le laisser.
Zunderscore
6

Vous devez également marquer la lettre unique comme facultative:

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

ou rendre la partie entière facultative

(([A-Z]{1}) +.*? +)?
Stefan
la source
1
Stefan, j'aimerais rendre la lettre totalement facultative. J'ai essayé les deux mais cela ne correspond toujours à rien. Je suis sûr que je me trompe. Pourriez-vous modifier votre exemple pour l'inclure dans la chaîne?
jim
0

Vous pouvez également utiliser une expression régulière plus simple conçue pour votre cas, comme (.*)\/(([^\?\n\r])*)$2correspond à ce que vous voulez.

robinvrd
la source