Escape de classes de caracteres unicode: \p{...}, \P{...}

Um escape de classe de caracteres unicode é um tipo de escape de classe de caracteres (en-US) que corresponde a um conjunto de caracteres especificado por uma propriedade Unicode. Este escape é suportado apenas no modo compatível com Unicode (en-US). Quando o marcador v (en-US) está habilitado, também pode ser usado para corresponder com textos de tamanho finito.

Experimente

Sintaxe

regex
\p{propriedadeSolitaria}
\P{propriedadeSolitaria}

\p{propriedade=valor}
\P{propriedade=valor}

Parâmetros

propriedadeSolitaria

Nome ou valor de uma propriedade Unicode solitária, seguindo a mesma sintaxe como valor. Ela especifica o valor para a propriedade General_Category (Categoria Geral), ou um nome binário de propriedade (en-US). No modo v (en-US), também pode ser uma propriedade Unicode binária de textos (en-US).

Nota: A sintaxe ICU (en-US) permite omitir o nome da propriedade Script também, mas o JavaScript não suporta isso, porque na maioria dos casos a propriedade Script_Extensions é mais útil que a Script.

propriedade

O nome de uma propriedade Unicode. Deve ser composto de letras ASCII (A–Z, a–z) e underscores (_), e deve ser um dos nome de propriedades não binárias (en-US).

valor

O valor de uma propriedade Unicode. Deve ser composto de letras (A–Z, a–z), underscores (_), e dígitos (0–9), e deve ser um dos valores suportados listados em PropertyValueAliases.txt (en-US).

Descrição

\p e \P são suportados apenas no modo compatível com Unicode (en-US). No modo compatível com Unicode, eles são escapes de caracteres (en-US) para o caractere p ou P.

Todo caracter Unicode possui um conjunto de propriedades que o descreve. Por exemplo, o caracter a (en-US) possui a propriedade General_Category com o valor Lowercase_Letter, e a propriedade Script com o valor Latn. As sequências de escape \p e \P permitem encontrar caracteres com base em suas propriedades. Por exemplo, a pode corresponder a \p{Lowercase_Letter} (o nome da propriedade General_Category é opcional) assim como \p{Script=Latn}. \P cria uma classe complementar que consiste de pontos de código sem a propriedade especificada.

Para compor múltiplas propriedades, use a sintaxe de intersecção de conjunto de caracteres (en-US) habilitada com o marcador v, ou veja padrão de subtração e intersecção (en-US).

No modo v, \p pode corresponder a uma sequências de pontos de código, definida no Unicode como "propriedades de textos". Isto é mais útil para emojis, que são frequentemente compostos por múltiplos pontos de código. Contudo, \P pode apenas complementar as propriedades do caracter.

Nota: Existem planos de portar a funcionalidade de propriedades de texto para o modo u também.

Exemplos

Categorias gerais

Categorias gerais são utilizada para classificar caracteres Unicode e subcategorias estão disponíveis para definir uma categorização mais precisa. É possível utilizar ambas as formas, curta ou longa, no escape de uma propriedade Unicode.

Elas podem ser utilizadas para corresponder a letras, números, símbolos, pontuações, espaços, etc. Para uma lista mais extensa de categorias gerais, por favor consulte a especificação Unicode (en-US).

js
// encontrando todas as letras de um texto
const estoria =
  "É o Gato Listrado: agora eu deve ter alguém com quem conversar.";

// Forma mais explícita
estoria.match(/\p{General_Category=Letter}/gu);

// Não é obrigatório usar o nome da propriedade para categorias gerais
estoria.match(/\p{Letter}/gu);

// Isso é equivalente (forma curta):
estoria.match(/\p{L}/gu);

// Isso também é equivalente (conjunção de todas as subcategorias usando a forma curta)
estoria.match(/\p{Lu}|\p{Ll}|\p{Lt}|\p{Lm}|\p{Lo}/gu);

Escritas e extensões de escritas

Algumas linguagens utilizam escritas diferentes para escrever seus sistemas. Por exemplo, inglês e espanhol são escritos utilizando latim enquanto árabe e russo são escritos utilizando outras escritas (respectivamente árabe e cirílico). As propriedades Unicode Script e Script_Extensions permitem que expressões regulares correspondam com caracteres de acordo com a escrita com a qual elas são amplamente utilizadas (Script) ou de acordo com o conjunto de escritas as quais elas pertencem (Script_Extensions).

Por exemplo, A pertence a escrita Latin (latim) e ε a escrita Greek (Grega).

js
const caracteresMisturados = "aεЛ";

// Utilizando o canonico nome "longo" da escrita
caracteresMisturados.match(/\p{Script=Latin}/u); // a

// Utilizando a forma curta (código ISO 15924) para a escrita
caracteresMisturados.match(/\p{Script=Grek}/u); // ε

// Utilizando o nome curto sc para a propriedade Script
caracteresMisturados.match(/\p{sc=Cyrillic}/u); // Л

Para mais detalhes, consulte a especificação Unicode (en-US), a especificação ECMAScript da tabela de escritas (en-US), e a lista de códigos de escritas ISO 15924 (en-US).

Se o caracter é utilizado em um conjunto limitado de escritas, a propriedade Script vai apenas combinar para a escrita "predominantemente" utilizada. Se nós queremos que os caracteres correspondam com base na escrita "não predominante", nós podemos utilizar a propriedade Script_Extensions (Scx para a forma curta).

js
// ٢ é o dígito 2 na notação Árabe-Índico
// enquanto ela é predominantemente escrita com a escrita Árabe
// ela ainda pode ser escrita na escrita Thaana

"٢".match(/\p{Script=Thaana}/u);
// null já que Thaana não é a escrita predominante

"٢".match(/\p{Script_Extensions=Thaana}/u);
// ["٢", index: 0, input: "٢", groups: undefined]

Escape de propriedades Unicode vs. Classes de caracteres

Com expressões regulares no JavaScript, também é possível usar classes de caracteres (en-US) e especialmente \w ou \d que correspondem a letras ou dígitos. Contudo, essas formas apenas correspondem a caracteres da escrita Latin (em outras palavras, de a à z e de A à Z para \w e de 0 à 9 para \d). Conforme mostrado neste exemplo (en-US), o trabalho com textos que não seguem a escrita Latim pode ser um pouco desajeitado.

Categorias de escape de propriedades Unicode abrangem muito mais caracteres e \p{Letter} ou \p{Number} vai funcionar para qualquer escrita.

js
// Tentando usar faixas de valores para evitar as limitações do \w:

const textoQueNaoELatim = "Приключения Алисы в Стране чудес";
const regexpPalavraBMP = /([\u0000-\u0019\u0021-\uFFFF])+/gu;
// BMP vai de U+0000 à U+FFFF mas o espaço é U+0020

console.table(textoQueNaoELatim.match(regexpPalavraBMP));

// Usando escapes de propriedades Unicode ao invés disso
const regexpUPE = /\p{L}+/gu;
console.table(textoQueNaoELatim.match(regexpUPE));

Correspondendo à preços

O exemplo a seguir corresponde a preços em um texto:

js
function pegarPrecos(str) {
  // Sc significa "currency symbol" (Símbolo de moeda)
  return [...str.matchAll(/\p{Sc}\s*[\d.,]+/gu)].map((match) => match[0]);
}

const str = `Rolinhos California $6.99
Rolinhos crocantes $8.49
Tempura de camarão $10.99`;
console.log(pegarPrecos(str)); // ["$6.99", "$8.49", "$10.99"]

const str2 = `Loja nos EUA $19.99
Loja na Europa €18.99
Loja no Japão ¥2000`;
console.log(pegarPrecos(str2)); // ["$19.99", "€18.99", "¥2000"]

Correspondendo à textos

Com o marcador v, \p{…} pode corresponder a textos que são potencialmente mais longos do que um caracter utilizando as propriedades de textos:

js
const marcador = "🇺🇳";
console.log(marcador.length); // 2
console.log(/\p{RGI_Emoji_Flag_Sequence}/v.exec(marcador)); // [ '🇺🇳' ]

Contudo, você não pode usar \P para corresponder a "um texto que não tem uma propriedade", porque não é claro quantos caracteres devem ser usados.

js
/\P{RGI_Emoji_Flag_Sequence}/v; // SyntaxError: Invalid regular expression: Invalid property name

Especificações

Specification
ECMAScript Language Specification
# prod-CharacterClassEscape

Compatibilidade com navegadores

BCD tables only load in the browser

Veja também