Estoy atrapado con una función regex. Ha sido bastante divertido desarrollarlo para llegar al punto en que está ahora, pero parece que no puedo mejorarlo aún más, incluso usando otros ejemplos en línea.
Tengo la siguiente función regex que estoy usando para detectar números de tarjeta de 16 dígitos,
(?<=^|[^0-9])[0-9]{16}(?=[^0-9]|$)|[0-9]{4}[-| |_][0-9]{4}[-| |_][0-9]{4}[-| |_][0-9]{4}
Esta función detecta los siguientes resultados,
1) 1234123412341234 (16 dígitos todos juntos)
2) 1234 1234 1234 1234
3) 1234-1234-1234-1234 (números de tarjeta con guiones y espacios)
4) Búscame 1234-1234-1234-1234 Búscame (números de tarjeta ocultos entre el texto)
Lo que estoy luchando por detener es los falsos positivos que obtengo, que sé que son un resultado directo de lograr el resultado número 4 anterior. Los falsos positivos son más de 16 dígitos que claramente no son números de tarjeta. P.ej
1) 1234-1234-1234-1234-1234
Cuando detecta los primeros 16 dígitos en la cadena, la expresión regular devuelve el valor. He creado un procedimiento que filtra estos falsos positivos, pero pensé que valía la pena ver si alguien puede mejorar lo anterior, para que otros puedan usar la función regex. Como otros ejemplos en Internet no parecían hacer el trabajo por mí.
2 respuestas
Puede usar
(?<!\d)\d{16}(?!\d)|(?<!\d[ _-])(?<!\d)\d{4}(?:[_ -]\d{4}){3}(?![_ -]?\d)
Consulte esta demostración de expresiones regulares.
O, si los delimitadores entre grupos deben ser iguales,
(?<!\d)\d{16}(?!\d)|(?<!\d[ _-])(?<!\d)\d{4}(?=([_ -]))(?:\1\d{4}){3}(?![_ -]?\d)
O desenrollado (sin la anticipación positiva):
(?<!\d)\d{16}(?!\d)|(?<!\d[ _-])(?<!\d)\d{4}([_ -])\d{4}(?:\1\d{4}){2}(?![_ -]?\d)
Consulte esta demostración de expresiones regulares.
Detalles
(?<!\d)\d{16}(?!\d)
: dieciséis dígitos no incluidos con ningún otro dígito|
- o(?<!\d[ _-])(?<!\d)
- una ubicación no precedida inmediatamente con un dígito o un dígito y espacio /_
/-
\d{4}
- cuatro dígitos(?:[_ -]\d{4}){3}
- tres repeticiones de un_
, espacio o-
y luego cuatro dígitos(?![_ -]?\d)
: una ubicación no seguida inmediatamente con un_
/ espacio opcional o-
y luego un dígito.
Simplificaría toda la expresión regular a \s((\d{4}[\s-]?){3}\d{4})\s
.
La diferencia es que estoy pidiendo 3 grupos de 4 dígitos más un separador opcional, luego otro grupo de 4 dígitos. De esa manera, estoy seguro de que siempre tengo 16. La \s
ayuda a delimitar al candidato, es posible que no necesite eso.
Prueba en https://regex101.com/
Preguntas relacionadas
Nuevas preguntas
regex
Las expresiones regulares proporcionan un lenguaje declarativo para hacer coincidir patrones dentro de cadenas. Se utilizan comúnmente para la validación, el análisis y la transformación de cadenas. Debido a que las expresiones regulares no están completamente estandarizadas, todas las preguntas con esta etiqueta también deben incluir una etiqueta que especifique el lenguaje de programación o la herramienta correspondiente.