Como posso usar expressões regulares compatíveis com Unicode em JavaScript?
Por exemplo, deve haver algo parecido \w
que possa corresponder a qualquer ponto de código na categoria Cartas ou Marcas (não apenas as ASCII), e esperamos ter filtros como [[P *]] para pontuação, etc.
javascript
regex
unicode
character-properties
Peter Mortensen
fonte
fonte
Respostas:
Situação para o ES 6
A próxima especificação de linguagem ECMAScript, edição 6, inclui expressões regulares compatíveis com Unicode. O suporte deve ser ativado com o
u
modificador na regex. Consulte Expressões regulares compatíveis com Unicode no ES6 .Até que o ES 6 seja concluído e amplamente adotado entre os fornecedores de navegadores, você ainda estará por sua conta. Atualização: agora existe um transpiler chamado regexpu que converte expressões regulares do ES6 Unicode em ES5 equivalente. Pode ser usado como parte do seu processo de construção. Experimente online.
Situação para ES 5 e abaixo
Embora o JavaScript opere em cadeias Unicode, ele não implementa classes de caracteres compatíveis com Unicode e não tem conceito de classes de caracteres POSIX ou blocos / subintervalos Unicode.
Problemas com Unicode nas expressões regulares do JavaScript
Verifique suas expectativas aqui: Testador Javascript RegExp Unicode Character Class ( Editar: a página original está inativa, o Internet Archive ainda possui uma cópia .)
O Flagrante Badassery tem um artigo sobre JavaScript, Regex e Unicode que lança alguma luz sobre o assunto.
Leia também Regex e Unicode aqui no SO. Provavelmente você precisa criar sua própria "classe de caracteres de pontuação".
Confira a Expressão regular: Combinar intervalo de blocos Unicode construtor , que permite construir uma expressão regular JavaScript que corresponda a caracteres que se enquadram em qualquer número de blocos Unicode especificados.
Acabei de fazer isso nas subintervalos "Pontuação geral" e "Pontuação suplementar", e o resultado é tão simples e direto quanto eu esperava:
Também existe o XRegExp , um projeto que oferece suporte a Unicode para JavaScript , oferecendo um mecanismo de regex alternativo com recursos estendidos.
E, claro, leitura obrigatória: mathiasbynens.be - JavaScript tem um problema Unicode :
fonte
u
sinalizador e outros recursos do ES6 para trabalhar com Unicode.u
expressões regulares."a品cd!e f".replace(/[^\w]/ug, "")
mas o regex resultante (executado no Chrome 59) ainda remove o品
caractere e só retorna"acdef"
Pessoalmente, prefiro não instalar outra biblioteca apenas para obter essa funcionalidade. Minha resposta não requer bibliotecas externas e também pode funcionar com poucas modificações para os tipos de expressões regulares além do JavaScript.
O site da Unicode fornece uma maneira de converter categorias Unicode em um conjunto de pontos de código. Por ser Unicode site , as informações devem ser precisas.
Observe que você precisará excluir os caracteres avançados, pois o JavaScript só pode manipular caracteres com menos de
FFFF
(hex). Sugiro marcar as caixas de seleção Abbreviate Collate e Escape, que equilibram o equilíbrio entre evitar caracteres não imprimíveis e minimizar o tamanho da expressão regular.Aqui estão algumas expansões comuns de diferentes propriedades Unicode:
\p{L}
(Cartas):\p{Nd}
(Número de dígitos decimais):\p{P}
(Pontuação):A página também reconhece várias classes de caracteres obscuras, como
\p{Hira}
, que são apenas os caracteres Hiragana (japoneses):Por fim, é possível conectar uma classe char com mais de uma propriedade Unicode para obter um regex mais curto do que você obteria apenas combinando-as (desde que determinadas configurações sejam verificadas).
fonte
\p
-Syntax parece não funcionar em JS,/\p{L}/.test('a')
é #false
Como também não encontrei uma boa solução, escrevi um pequeno script há muito tempo, baixando dados da especificação unicode (v.5.0.0) e gerando intervalos para cada categoria e subcategoria unicode no BMP (recentemente substituído por um pequeno Programa Java que usa seu próprio suporte nativo a Unicode).
Basicamente, ele se converte
\p{...}
em uma faixa de valores, assim como a saída da ferramenta mencionada por Tomalak, mas os intervalos podem acabar bem grandes (já que não se trata de blocos, mas de caracteres espalhados por muitos lugares diferentes).Por exemplo, um Regex escrito assim:
Será convertido para algo como isto:
Não o usei muito na prática, mas parece funcionar bem nos meus testes, por isso estou publicando aqui caso alguém ache útil. Apesar do tamanho das expressões regulares resultantes (o exemplo acima possui 3591 caracteres quando expandido), o desempenho parece aceitável (consulte os testes em jsFiddle; obrigado a @modiX e @Lwangaman pelas melhorias).
Aqui está a fonte (bruta, 27,5 KB; minificada , 24,9 KB, não muito melhor ...). Ele pode ser menores por unescaping os caracteres Unicode, mas OTOH vai correr o risco de problemas de codificação, por isso estou deixando como ela é. Espero que com o ES6 esse tipo de coisa não seja mais necessário.
Atualização : parece a mesma estratégia adotada no plug-in XRegExp Unicode mencionado por Tim Down, exceto que, neste caso, estão sendo usadas expressões regulares regulares em JavaScript.
fonte
/^\p{L}+$/
deve corresponder,東海林
mas não corresponde. Sempre que você atualizar a coleção, informe-me. Muito obrigado.\p{Lo}
, perde as duas tabelas Kanji.Conforme mencionado em outras respostas, as expressões regulares do JavaScript não têm suporte para classes de caracteres Unicode. No entanto, existe uma biblioteca que fornece isso: o excelente XRegExp de Steven Levithan e seu plug-in Unicode .
fonte
[^\u0000-\u007F]+
para quaisquer caracteres que não estejam incluídos caracteres ASCII.Por exemplo:
Aqui estão algumas referências perfeitas:
Gerador RegExp de intervalo Unicode
Expressões regulares Unicode
Gráficos de código de caracteres 10.0 Unicode
Corresponder ao intervalo de blocos Unicode
fonte
Setembro de 2018 (atualizado em fevereiro de 2019)
Parece que regexp
/\p{L}/u
para letras de correspondência (como categorias unicode )Aqui está um exemplo de trabalho
Eu relato esse bug aqui .
Atualizar
Após mais de 2 anos, de acordo com: 1500035 > 1361876 > 1634135, finalmente este bug foi corrigido e estará disponível no Firefox v.78 +
fonte
Isso fará isso:
Ele seleciona explicitamente um intervalo de caracteres unicode. Funcionará para caracteres latinos, mas outros caracteres estranhos podem estar fora desse intervalo.
fonte
\u0100
e\u0280
: muitos deles podem ser considerados caracteres latinos, mas outros não: var s = ''; for (var i = 0xff; i <= 0x280; i ++) {s + = String.fromCharCode (i)} "ÿĀāÃ㥹ĆćĈĉĊċČčĎďĐđĒēĔĕĖėĘęĚěĜĝĞğĠġĢģĤĥĦħĨĩĪīĬĭĮįİıIJijĴĵĶķĸĹĺĻļĽľĿŀŁłŃńŅņŇňʼnŊŋŌō ... ..."Em JavaScript, \ we \ d são ASCII, enquanto \ s é Unicode. Não me pergunte o porquê. O JavaScript suporta \ p com categorias Unicode, que você pode usar para emular um \ w e \ d com suporte a Unicode.
Para \ d, use \ p {N} (números)
Para \ w use [\ p {L} \ p {N} \ p {Pc} \ p {M}] (letras, números, sublinhados, marcas)
Atualização: Infelizmente, eu estava errado sobre isso. O JavaScript também não suporta oficialmente \ p, embora algumas implementações ainda possam suportar isso. O único suporte a Unicode nas expressões regulares do JavaScript corresponde a pontos de código específicos com \ uFFFF. Você pode usar aqueles em intervalos nas classes de caracteres.
fonte
/\p{L}+/u
Se você estiver usando o Babel , o suporte a Unicode já estará disponível.
Também liberei um plugin que transforma seu código-fonte para que você possa escrever expressões regulares como
/^\p{L}+$/
. Eles serão transformados em algo que os navegadores entendem.Aqui está a página do projeto do plugin:
babel-plugin-utf-8-regex
fonte
Estou respondendo a esta pergunta
Qual seria o equivalente para \ p {Lu} ou \ p {Ll} no regExp para js?
pois foi marcado como uma duplicata exata da pergunta antiga atual.
Consultando o banco de dados UCD do Unicode 12, \ p {Lu} gera 1.788 pontos de código.
A conversão para UTF-16 produz a equivalência de construção de classe.
É apenas uma sequência de caracteres de 4k e é facilmente executável em qualquer mecanismo de expressão regular.
Consultando o banco de dados UCD do Unicode 12, \ p {Ll} gera 2.151 pontos de código.
A conversão para UTF-16 produz a equivalência de construção de classe.
Observe que uma implementação regex de \ p {Lu} ou \ p {Pl} realmente chama uma
função não padrão para testar o valor.
As classes de caracteres mostradas aqui são feitas de maneira diferente e são lineares, padrão
e bastante lentas, quando atoladas em uma única classe.
Algumas dicas sobre como um mecanismo Regex (em geral) implementa as Classes de propriedades Unicode:
Examine essas características de desempenho entre a propriedade
e o bloco de classes (como acima)
Uau que diferença !!
Vamos ver como as propriedades podem ser implementadas
Matriz de ponteiros [10FFFF] onde cada índice é um ponto de código
Cada ponteiro na matriz é para uma estrutura de classificação.
Uma estrutura de classificação contém elemets de campo fixo.
Alguns são NULL e não pertencem.
Alguns contêm classificações de categoria.
Exemplo: Categoria Geral
Este é um elemento de bitmap que usa 17 de 64 bits.
Tudo o que este Code Point suporta, tem bits definidos como uma máscara.
-Close_Punctuation
-Connector_Punctuation
-Control
-Currency_Symbol
-Dash_Punctuation
-Decimal_Number
-Enclosing_Mark
-Final_Punctuation
-Formato
-Initial_Punctuation
-Letter_Number
-Line_Separator
-Lowercase_Letter
-Math_Symbol
-Modifier_Letter
-Modifier_Symbol
-Nonspacing_Mark
-Open_Punctuation
-Other_Letter
-Other_Number
-Other_Punctuation
-Other_Symbol
-Paragraph_Separator
-Private_Use
-Space_Separator -Substituto
-Spacing_Mark
-Titlecase_Letter
-Unassigned
-Uppercase_Letter
Quando um regex é analisado com algo assim \ p {Lu},
é traduzido diretamente para
Outro exemplo, quando um regex é analisado com a propriedade de pontuação \ p {P},
é convertido em
Uma verificação desse elemento para qualquer um desses bits de itens, que são unidos a uma máscara:
-Close_Punctuation
-Connector_Punctuation
-Dash_Punctuation
-Final_Punctuation
-Initial_Punctuation
-Open_Punctuation
-Other_Punctuation
O deslocamento e o bit ou bit (máscara) são armazenados como uma etapa de regex para essa propriedade.
A tabela de pesquisa é criada uma vez para todos os pontos de código Unicode usando essa matriz.
Quando um caractere é verificado, é tão simples quanto usar o CP como um índice nessa matriz e verificar o elemento específico da estrutura de classificação para esse bit (máscara).
Essa estrutura é expansível e indireta para fornecer pesquisas muito mais complexas. Este é apenas um exemplo simples.
Compare essa pesquisa direta com uma pesquisa de classe de caractere:
Todas as classes são uma lista linear de itens pesquisados da esquerda para a direita.
Nesta comparação, considerando que a string de destino contém apenas apenas as letras maiúsculas e minúsculas completas, a lei das médias preveria que metade dos itens da classe precisaria ser verificada à distância para encontrar uma correspondência.
Essa é uma enorme desvantagem no desempenho.
No entanto, se as tabelas de pesquisa não estiverem lá ou não estiverem atualizadas com a versão mais recente do Unicode (12 nesta data)
, essa seria a única maneira.
Na verdade, é principalmente a única maneira de obter os
caracteres Emoji completos , pois não há propriedade específica (ou raciocínio) em sua atribuição.
fonte
Você também pode usar:
fonte