No artigo da Wikipedia sobre Expressões regulares , parece que [[:digit:]]
= [0-9]
= \d
.
Quais são as circunstâncias em que eles não são iguais? Qual é a diferença?
Após algumas pesquisas, acho que uma diferença é que a expressão entre colchetes [:expr:]
depende da localidade.
regular-expression
wildcards
harbinn
fonte
fonte
Respostas:
Sim, é
[[:digit:]]
~[0-9]
~\d
(onde ~ significa aproximado).Na maioria das linguagens de programação (onde é suportado)
\d
≡[[:digit:]]
(idêntico).O
\d
é menos comum que[[:digit:]]
(não no POSIX, mas no GNUgrep -P
).Existem muitos dígitos no UNICODE , por exemplo:
123456789 # Hindu-Arabic
algarismos arábicos٠١٢٣٤٥٦٧٨٩ # ARABIC-INDIC
۰۱۲۳۴۵۶۷۸۹ # EXTENDED ARABIC-INDIC/PERSIAN
߀߁߂߃߄߅߆߇߈߉ # NKO DIGIT
०१२३४५६७८९ # DEVANAGARI
Tudo isso pode ser incluído em
[[:digit:]]
ou\d
.Em vez disso,
[0-9]
geralmente são apenas os dígitos ASCII0123456789
.Existem muitas linguagens: Perl, Java, Python, C. Na qual
[[:digit:]]
(e\d
) exige um significado estendido. Por exemplo, esse código perl corresponderá a todos os dígitos acima:O que equivale a selecionar todos os caracteres que possuem as propriedades Unicode
Numeric
edigits
:Qual grep poderia reproduzir (a versão específica do pcre pode ter uma lista interna diferente de pontos de código numérico que o Perl):
Altere para [0-9] para ver:
POSIX
Para o POSIX BRE ou ERE específico:
O
\d
não é suportado (não no POSIX, mas no GNUgrep -P
).[[:digit:]]
é exigido pelo POSIX para corresponder à classe de caracteres de dígito, que por sua vez é exigida pela ISO C como sendo os caracteres de 0 a 9 e nada mais. Assim, apenas em C locale tudo[0-9]
,[0123456789]
,\d
e[[:digit:]]
significam exatamente a mesma. O[0123456789]
não possui possíveis interpretações errôneas,[[:digit:]]
está disponível em mais utilitários e é comum apenas significar[0123456789]
. O\d
é suportado por alguns utilitários.Quanto a
[0-9]
, o significado das expressões de intervalo é definido apenas pelo POSIX no código de idioma C; em outros locais, pode ser diferente (pode ser uma ordem de ponto de código ou ordem de intercalação ou outra coisa).cartuchos
Algumas implementações podem entender um intervalo como algo diferente da ordem ASCII simples (ksh93 por exemplo):
E essa é uma fonte segura de bugs esperando para acontecer.
fonte
iswctype()
e BRE / ERE / curingas nos utilitários POSIX, [0-9] e [[: digit:]] correspondem apenas a 0123456789. E isso será explicitado na próxima revisão do padrãoperl
é\d
no modo Unicode combinados em dígitos decimais de outros scripts. Obrigado por isso. Com o PCRE, veja(*UCP)
como no GNUgrep -Po '(*UCP)\d'
ougrep -Po '(*UCP)[[:digit:]]
para que as classes sejam baseadas nas propriedades Unicode.[:digit:]
sintaxe sugere que você deseja usar a localização, ou seja, o que o usuário considerar como um dígito. Eu nunca uso[:digit:]
porque, na prática, é o mesmo que,[0-9]
em qualquer caso, invariavelmente quero corresponder em 0123456789, nunca pretendo corresponder٠١٢٣٤٥٦٧٨٩
e não consigo pensar em um caso de uso em que alguém deseje corresponder em um dígito decimal em qualquer script com utilitários POSIX. Veja também a discussão atual sobre[:blank:]
o zsh ML . Essas classes de personagens são um pouco confusas.Isso depende de como você define um dígito;
[0-9]
tende a ser apenas os ASCII (ou possivelmente algo que não seja ASCII nem um superconjunto de ASCII, mas com os mesmos 10 dígitos que em ASCII apenas com diferentes representações de bits (EBCDIC));\d
por outro lado, pode ser apenas os dígitos simples (versões antigas do Perl, ou versões modernas do Perl com o/a
sinalizador de expressão regular ativado) ou pode ser uma correspondência Unicode da\p{Digit}
qual é um conjunto maior de dígitos do que[0-9]
ou/\d/a
correspondência.perldoc perlrecharclass
para obter mais informações ou consulte a documentação do idioma em questão para ver como ele se comporta.Mas espere, tem mais! O código do idioma também pode variar o que
\d
corresponde, portanto,\d
pode corresponder a menos dígitos do que o conjunto Unicode completo desse tipo e (espero, geralmente) também inclui[0-9]
. Isso é semelhante à diferença em C entreisdigit(3)
([0-9]
) eisnumber(3)
([0-9
mais qualquer outra coisa do código do idioma).Pode haver chamadas que podem ser feitas para obter o valor do dígito, mesmo que não seja
[0-9]
:fonte
isnumber()
é uma coisa BSD, pelo menos com base na página homem parece tão[0-9]
.Significado diferente de
[0-9]
,[[:digit:]]
e\d
são apresentados em outras respostas. Aqui eu gostaria de adicionar diferenças na implementação do mecanismo regex.Então
[[:digit:]]
sempre funciona ,\d
depende. No manual do grep, é mencionado que[[:digit:]]
é apenas0-9
noC
local.PS1: Se você souber mais, expanda a tabela.
PS2: GNU grep 3.1 e GNU 4.4 são usados para teste.
fonte
grep
esed
, com a maior diferença provavelmente entre as versões GNU e outras. Essa resposta pode ser mais útil se mencionar a qual versãogrep
e a quesed
ela se refere. Ou qual é a fonte dessa tabela, nesse caso. 2) que a tabela pode muito bem ser transcrita para texto, uma vez que não contém qualquer coisa que exige que ele seja uma imagemre
módulo interno do python não suporta [[: digit:]], mas a biblioteca add inregex
o suporta, então eu iria me incomodar um pouco com o que sempre funciona. Ele sempre funciona em situações de reclamação posix.As diferenças teóricas já foram bem explicadas nas outras respostas, por isso resta explicar as diferenças práticas .
Aqui estão alguns dos casos de uso mais comuns para combinar um dígito:
Extração de dados de uma só vez
Freqüentemente, quando você deseja triturar alguns números, os próprios números estão em um arquivo de texto formatado de forma desajeitada. Você deseja extraí-los para uso em seu programa. Provavelmente, você pode dizer o formato do número (olhando o arquivo) e sua localidade atual; portanto, não há problema em usar qualquer um dos formulários , desde que o trabalho seja feito.
\d
requer o menor número de pressionamentos de tecla, por isso é muito comum.Desinfecção de entrada
Você tem alguma entrada de usuário não confiável (talvez de um formulário da Web) e precisa garantir que ela não contenha surpresas. Talvez você queira armazená-lo em um campo numérico em um banco de dados ou use como parâmetro em um comando shell para executar em um servidor. Nesse caso, você realmente quer
[0-9]
, já que é o mais restritivo e previsível.Data de validade
Você tem alguns dados que não usará para nada "perigoso", mas seria bom saber se é um número. Por exemplo, seu programa permite que o usuário insira um endereço e você deseja destacar um possível erro de digitação se a entrada não contiver um número da casa. Nesse caso, você provavelmente quer ser o mais amplo possível, assim
[[:digit:]]
é o caminho a percorrer.Esses seriam os três casos de uso mais comuns para correspondência de dígitos. Se você acha que eu perdi uma importante, por favor mande um comentário.
fonte