Regex cómo hacer coincidir un personaje opcional

147

Tengo una expresión regular que pensé que funcionaba correctamente hasta ahora. Necesito hacer coincidir un personaje opcional. Puede estar allí o no.

Aquí hay dos cadenas. La cadena superior coincide, mientras que la inferior no. La ausencia de una sola letra en la cadena inferior es lo que hace que falle.

Me gustaría obtener la letra única después de los 5 dígitos iniciales si está allí y si no, continuar obteniendo el resto de la cadena. Esta carta puede ser A-Z.

Si elimino ([A-Z]{1}) +.*? +de la expresión regular, coincidirá con todo lo que necesito, excepto la letra, pero es algo importante.

20000      K               Q511195DREWBT            E00078748521
30000                      K601220PLOPOH            Z00054878524

Aquí está la expresión regular que estoy usando.

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

Respuestas:

247

Utilizar

[A-Z]?

para hacer la carta opcional. {1}Es redundante. (Por supuesto, también podría escribir [A-Z]{0,1}lo que significaría lo mismo, pero para eso ?está allí).

Podrías mejorar tu expresión regular para

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

Y, dado que en la mayoría de los dialectos de expresiones regulares, \des lo mismo 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})

Pero: ¿realmente necesitas 11 grupos de captura separados? Y si es así, ¿por qué no captura el penúltimo grupo de dígitos?

Tim Pietzcker
fuente
Tim, honestamente no estoy seguro ya que no escribí esta expresión regular. Todavía soy bastante nuevo en regex. Si ve una mejor manera de escribir esto, estoy abierto a sugerencias.
Jim
1
Tim, tu ejemplo funciona para ambas cadenas si tengo una letra en esa posición o no. Gracias.
Jim
26

Puede hacer que la letra única sea opcional agregando un ?después como:

([A-Z]{1}?)

El cuantificador {1}es redundante, por lo que puede soltarlo.

codictorio
fuente
Gracias codeaddict. ¿El signo de interrogación toma el lugar del `+. *? + `?
Jim
Cuando utilice grep regex, obtendrá un error si suelta el {1} ​​(grep: la aserción retrospectiva no tiene una longitud fija). Así que ese es un caso para dejarlo.
Zunderscore
6

También debe marcar la letra única como opcional:

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

o hacer que toda la parte sea opcional

(([A-Z]{1}) +.*? +)?
Stefan
fuente
1
Stefan, me gustaría hacer que la carta sea totalmente opcional. Probé ambos pero todavía no coincide con nada. Estoy seguro de que me he equivocado. ¿Podría modificar su ejemplo para incluirlo en la cadena?
Jim
0

También puede usar expresiones regulares más simples diseñadas para su caso, como (.*)\/(([^\?\n\r])*)dónde $2coincide con lo que desea.

robinvrd
fuente