Eu olhei no Stack Overflow ( substituindo caracteres ... eh , como o JavaScript não segue o padrão Unicode referente ao RegExp etc.) e não encontrei realmente uma resposta concreta para a pergunta:
How can JavaScript match for accented characters (those with diacritical marks)?
Estou forçando um campo em uma interface do usuário para corresponder ao formato: last_name, first_name
(último [espaço de vírgula] primeiro) e quero fornecer suporte para sinais diacríticos, mas evidentemente no JavaScript é um pouco mais difícil do que em outros idiomas / plataformas.
Esta foi a minha versão original, até eu querer adicionar suporte diacrítico:
/^[a-zA-Z]+,\s[a-zA-Z]+$/
Atualmente, estou debatendo um dos três métodos para adicionar suporte, todos os quais testei e trabalho (pelo menos até certo ponto, não sei realmente qual é a "extensão" da segunda abordagem). Aqui estão eles:
Listar explicitamente todos os caracteres acentuados que eu gostaria de aceitar como válidos (coxos e excessivamente complicados):
var accentedCharacters = "àèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ";
// Build the full regex
var regex = "^[a-zA-Z" + accentedCharacters + "]+,\\s[a-zA-Z" + accentedCharacters + "]+$";
// Create a RegExp from the string version
regexCompiled = new RegExp(regex);
// regexCompiled = /^[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+,\s[a-zA-ZàèìòùÀÈÌÒÙáéíóúýÁÉÍÓÚÝâêîôûÂÊÎÔÛãñõÃÑÕäëïöüÿÄËÏÖÜŸçÇßØøÅåÆæœ]+$/
- Isso corresponde corretamente a um nome / sobrenome com qualquer um dos caracteres acentuados suportados
accentedCharacters
.
Minha outra abordagem foi usar a .
classe de caracteres, para ter uma expressão mais simples:
var regex = /^.+,\s.+$/;
- Isso iria corresponder para praticamente nada, pelo menos na forma de:
something, something
. Tudo bem, suponho ...
A última abordagem, que acabei de descobrir, pode ser mais simples ...
/^[a-zA-Z\u00C0-\u017F]+,\s[a-zA-Z\u00C0-\u017F]+$/
- Ele corresponde a uma variedade de caracteres unicode - testados e funcionando, embora eu não tenha tentado nada louco, apenas as coisas normais que vejo em nosso departamento de idiomas para nomes de membros da faculdade.
Aqui estão as minhas preocupações:
- A primeira solução é muito limitadora e desleixada e complicada. Precisaria ser mudado se eu esquecesse um personagem ou dois, e isso não é muito prático.
- A segunda solução é melhor, concisa, mas provavelmente corresponde muito mais do que realmente deveria. Não consegui encontrar nenhuma documentação real sobre exatamente o que
.
corresponde, apenas a generalização de "qualquer caractere, exceto o caractere de nova linha" (de uma tabela no MDN ). A terceira solução parece ser a mais precisa, mas existem algumas dicas? Eu não sou muito familiarizado com Unicode, pelo menos na prática, mas olhando para um código de mesa / continuação dessa mesa ,
\u00C0-\u017F
parece ser bastante sólido, pelo menos para a minha entrada esperado.- O corpo docente não enviará formulários com seus nomes no idioma nativo (por exemplo, árabe, chinês, japonês etc.), para que eu não precise me preocupar com caracteres fora do conjunto de caracteres latinos
Portanto, a (s) questão (s) real (is) : Qual dessas três abordagens é mais adequada para a tarefa? Ou existem soluções melhores?
fonte
regex = /^[^,]+,\s[^,]+$/;
para evitar isso..
átomo corresponde a qualquer coisa, exceto as novas linhas ", na verdade, é bem exato :-)Respostas:
A maneira mais fácil de aceitar todos os sotaques é esta:
Consulte https://unicode-table.com/en/ para caracteres listados em ordem numérica.
fonte
-
define um intervalo, e esta técnica explora a ordenação de caracteres no conjunto de caracteres para definir uma faixa contínua, contribuindo para uma solução concisa super para o problemaZ
ea
)?O intervalo latino acentuado
\u00C0-\u017F
não era suficiente para o meu banco de dados de nomes, então estendi a regex paraEu adicionei esses blocos de código (
\u00C0-\u024F
inclui três blocos adjacentes ao mesmo tempo):\u00C0-\u00FF
Suplemento Latin-1\u0100-\u017F
Latim estendido-A\u0180-\u024F
Latim estendido-B\u1E00-\u1EFF
Adicional Latino EstendidoObserve que,
\u00C0-\u00FF
na verdade, é apenas uma parte do suplemento Latin-1 . Esse intervalo ignora os sinais de controle não imprimíveis e todos os símbolos, com exceção da multiplicação desajeitadamente ×\u00D7
e divisão ÷\u00F7
.Se você precisar de mais pontos de código, poderá encontrar mais intervalos na lista de caracteres Unicode da Wikipedia . Por exemplo, você também pode adicionar Latin Extended-C , D e E , mas eu os deixei de fora porque apenas os historiadores parecem interessados neles agora, e os conjuntos D e E nem sequer são renderizados corretamente no meu navegador.
O regex original que parou em
\u017F
borked com o nome "Șenol". De acordo com o Unicode Analyzer da FontSpace , esse primeiro caractere é\u0218
, LETRAS MAIÚSCULAS LATINA COM Vírgula abaixo. (Sim, geralmente é soletrado com um cedilla-S\u015E
, "olenol". Mas não estou voando para a Turquia para dizer a ele: "Você está escrevendo seu nome errado!")fonte
[a-zA-Z\u00c0-\u024f\u1e00-\u1eff]
Depende da tarefa :-) Para corresponder exatamente a todos os caracteres latinos e suas versões acentuadas, os intervalos Unicode provavelmente fornecem a melhor solução. Eles podem ser estendidos a todos os caracteres que não sejam espaços em branco, o que pode ser feito usando a
\S
classe de caracteres.O problema mais básico que estou vendo aqui não são diacríticos, mas espaços em branco. Existem alguns nomes que consistem em várias palavras, por exemplo, para títulos. Portanto, você deve usar o mais genérico, que permite tudo, menos a vírgula que distingue o primeiro e o sobrenome:
Mas sua segunda solução com a
.
classe de caracteres é tão boa quanto você, então você pode precisar se preocupar com várias vírgulas.fonte
any_character_not_a_comma, any_character_not_a_comma
? Foi o que pensei quando li pela primeira vez. Fiquei meio confuso quando vi três vírgulas lá.s
no espaço em branco ...[^\s]
para\S
A biblioteca XRegExp possui um plug-in chamado Unicode que ajuda a resolver tarefas como essa.
É mencionado nos comentários da pergunta, mas é fácil perder. Percebi isso somente depois que enviei esta resposta.
fonte
anything, anything
. Isso será útil para futuros leitores :)Que tal agora?
fonte
Šš
.Que tal isso?
Combina todas as palavras com caracteres acentuados ou não.
fonte
deste wiki: https://en.wikipedia.org/wiki/List_of_Unicode_characters#Basic_Latin
para letras latinas, eu uso
evita hífens e caracteres especiais
fonte
Explicação:
\pL
- corresponde a qualquer tipo de letra de qualquer idioma\pM
- alcança um caractere que deve ser combinado com outro caractere (por exemplo, acentos, trema, caixas anexas, etc.)\p{Zs}
- corresponde a um caractere de espaço em branco invisível, mas ocupa espaçou
- Strings de padrão e assunto são tratados como UTF-8Diferente de outros regex propostos (como
[A-Za-zÀ-ÖØ-öø-ÿ]
), isso funcionará com todos os caracteres específicos do idioma, por exemplo,Šš
é correspondido por esta regra, mas não por outros nesta página.Infelizmente, o JavaScript nativo não suporta essas classes. No entanto, você pode usar
xregexp
, por exemplo,fonte
Você pode remover os diacríticos dos alfabetos usando:
Ele removerá todas as marcas diacríticas e executará sua regex nele
Referência:
https://thread.engineering/2018-08-29-searching-and-sorting-text-with-diacritical-marks-in-javascript/
fonte