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

Baseline Widely available

This feature is well established and works across many devices and browser versions. It’s been available across browsers since July 2015.

Um escape de classe de caracteres unicode é um tipo de escape de classe de caracteres que corresponde a um conjunto de caracteres especificado por uma propriedade Unicode. Este escape é suportado apenas no modo compatível com Unicode. Quando o marcador v 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, 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. No modo compatível com Unicode, eles são escapes de caracteres 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 habilitada com o marcador v, ou veja padrão de subtração e intersecção.

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 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, 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