En el artículo de Wikipedia sobre expresiones regulares , parece que [[:digit:]]
= [0-9]
= \d
.
¿Cuáles son las circunstancias en las que no son iguales? ¿Cuál es la diferencia?
Después de investigar un poco, creo que una diferencia es que la expresión entre paréntesis [:expr:]
depende de la configuración regional.
regular-expression
wildcards
harbinn
fuente
fuente
Respuestas:
Sí, es
[[:digit:]]
~[0-9]
~\d
(donde ~ significa aproximado).En la mayoría de los lenguajes de programación (donde es compatible)
\d
≡[[:digit:]]
(idéntico).El
\d
es menos común que[[:digit:]]
(no en POSIX pero está en GNUgrep -P
).Hay muchos dígitos en UNICODE , por ejemplo:
123456789 # Hindu-Arabic
Números arábigos٠١٢٣٤٥٦٧٨٩ # ARABIC-INDIC
۰۱۲۳۴۵۶۷۸۹ # EXTENDED ARABIC-INDIC/PERSIAN
߀߁߂߃߄߅߆߇߈߉ # NKO DIGIT
०१२३४५६७८९ # DEVANAGARI
Todo lo cual puede estar incluido en
[[:digit:]]
o\d
.En cambio,
[0-9]
generalmente son solo los dígitos ASCII0123456789
.Hay muchos lenguajes: Perl, Java, Python, C. En los cuales
[[:digit:]]
(y\d
) requiere un significado extendido. Por ejemplo, este código perl coincidirá con todos los dígitos de arriba:Lo que equivale a seleccionar todos los caracteres que tienen las propiedades Unicode de
Numeric
ydigits
:Qué grep podría reproducirse (la versión específica de pcre puede tener una lista interna diferente de puntos de código numérico que Perl):
Cámbielo a [0-9] para ver:
POSIX
Para el POSIX BRE o ERE específico:
El
\d
no es compatible (no en POSIX pero está en GNUgrep -P
).[[:digit:]]
POSIX requiere que se corresponda con la clase de caracteres de dígitos, que a su vez ISO C requiere que sean los caracteres del 0 al 9 y nada más. Así que sólo en C locale todo[0-9]
,[0123456789]
,\d
y[[:digit:]]
significan exactamente lo mismo. No[0123456789]
tiene posibles interpretaciones erróneas,[[:digit:]]
está disponible en más utilidades y es común que solo signifique[0123456789]
. El\d
es compatible con pocas utilidades.En cuanto a
[0-9]
, el significado de las expresiones de rango solo está definido por POSIX en la configuración regional C; en otros entornos locales puede ser diferente (puede ser el orden de los puntos de código o el orden de clasificación u otra cosa).conchas
Algunas implementaciones pueden entender que un rango es algo diferente del orden ASCII simple (por ejemplo, ksh93):
Y esa es una fuente segura de errores que esperan suceder.
fuente
iswctype()
y BRE / ERE / comodines en las utilidades POSIX, [0-9] y [[: digit:]] coinciden solo en 0123456789. Y eso se hará explícito en la próxima revisión de la normaperl
el\d
modo Unicode coincidía con dígitos decimales de otros scripts. Gracias por eso. Con PCRE, vea(*UCP)
como en GNUgrep -Po '(*UCP)\d'
ogrep -Po '(*UCP)[[:digit:]]
para que las clases se basen en propiedades Unicode.[:digit:]
sintaxis sugeriría que desea utilizar la localización, eso es lo que el usuario considere como un dígito. Nunca lo uso[:digit:]
porque en la práctica es lo mismo[0-9]
y, en cualquier caso, siempre quiero coincidir en 0123456789, nunca quiero hacerlo٠١٢٣٤٥٦٧٨٩
, y no puedo pensar en un caso de uso en el que uno quisiera coincidir en un dígito decimal en cualquier script con utilidades POSIX. Vea también la discusión actual sobre[:blank:]
zsh ML . Esas clases de personajes son un poco desordenadas.Esto depende de cómo defina un dígito;
[0-9]
tiende a ser solo ASCII (o posiblemente algo más que no sea ASCII ni un superconjunto de ASCII sino los mismos 10 dígitos que en ASCII solo con diferentes representaciones de bits (EBCDIC));\d
por otro lado, podría ser solo los dígitos simples (versiones antiguas de Perl o versiones modernas de Perl con el/a
indicador de expresión regular habilitado) o podría ser una coincidencia Unicode,\p{Digit}
que es más bien un conjunto de dígitos más grande que[0-9]
o/\d/a
coincidente.perldoc perlrecharclass
para obtener más información o consulte la documentación del idioma en cuestión para ver cómo se comporta.¡Pero espera hay mas! La configuración regional también puede variar qué
\d
coincide, por lo que\d
podría coincidir con menos dígitos que el conjunto Unicode completo de los mismos, y (con suerte, generalmente) también incluye[0-9]
. Esto es similar a la diferencia en C entreisdigit(3)
([0-9]
) yisnumber(3)
([0-9
más cualquier otra cosa de la configuración regional).Puede haber llamadas que se pueden hacer para obtener el valor del dígito, incluso si no es así
[0-9]
:fuente
isnumber()
es una cuestión de BSD, al menos según la página de manual que parece ser[0-9]
.Diferente significado de
[0-9]
,[[:digit:]]
y\d
se presentan en otras respuestas. Aquí me gustaría agregar diferencias en la implementación del motor regex.Así que
[[:digit:]]
siempre funciona ,\d
depende. En el manual de grep se menciona que[[:digit:]]
solo está0-9
en laC
configuración regional.PS1: Si sabes más, expande la tabla.
PS2: GNU grep 3.1 y GNU 4.4 se utilizan para la prueba.
fuente
grep
ysed
, con la mayor diferencia probablemente entre las versiones de GNU frente a otras. Esta respuesta podría ser más útil si menciona a qué versióngrep
ysed
se refiere. O cuál es la fuente de esa tabla, para el caso. 2) esa tabla también podría transcribirse al texto, ya que no contiene nada que requiera que sea una imagenre
módulo incorporado de Python no admite [[: digit:]] pero la biblioteca de complementosregex
sí lo admite, por lo que me molestaría un poco que siempre funcione. Siempre funciona en situaciones de queja posix.Las diferencias teóricas ya se han explicado bastante bien en las otras respuestas, por lo que queda por explicar las diferencias prácticas .
Estos son algunos de los casos de uso más comunes para hacer coincidir un dígito:
Extracción de datos de una sola vez
A menudo, cuando desea agrupar algunos números, los números mismos se encuentran en un archivo de texto con un formato extraño. Desea extraerlos para usarlos en su programa. Probablemente pueda decir el formato de número (mirando el archivo) y su ubicación actual, por lo que está bien usar cualquiera de los formularios , siempre que haga el trabajo.
\d
requiere la menor cantidad de pulsaciones de teclas, por lo que se usa con mucha frecuencia.Desinfección de entrada
Tiene una entrada de usuario no confiable (tal vez de un formulario web), y debe asegurarse de que no contenga ninguna sorpresa. Tal vez desee almacenarlo en un campo numérico en una base de datos, o usarlo como parámetro de un comando de shell para ejecutarlo en un servidor. En este caso, realmente quieres
[0-9]
, ya que es el más restrictivo y predecible.Validación de datos
Tiene un poco de información que no va a utilizar para nada "peligroso", pero sería bueno saber si es un número. Por ejemplo, su programa le permite al usuario ingresar una dirección, y usted desea resaltar un posible error tipográfico si la entrada no contiene un número de casa. En este caso, probablemente desee ser lo más amplio posible, por lo que
[[:digit:]]
es el camino a seguir.Parecen ser los tres casos de uso más comunes para la coincidencia de dígitos. Si crees que me perdí uno importante, por favor deja un comentario.
fuente