1001Ferramentas
🚩Validadores

Validador de Bandeira Emoji

Verifica se um emoji é uma bandeira de país válida (composto de Regional Indicator Symbols). Mostra o código ISO 3166-1 alpha-2 correspondente.

Validação de emoji de bandeira: como o Unicode codifica um país em dois caracteres

Um emoji de bandeira como 🇧🇷 não é um único caractere no Unicode — é um par de Regional Indicator Symbol Letters (RIS) que juntos formam o código ISO 3166-1 alpha-2 do país. A bandeira do Brasil é a letra B + R renderizada em sequência: 🇧 (U+1F1E7) seguido de 🇷 (U+1F1F7). A bandeira dos Estados Unidos é 🇺 + 🇸 (U+1F1FA + U+1F1F8). A fonte e o sistema operacional são a única coisa que transforma o par em um glifo de bandeira de verdade — em nível de bytes são só duas letras indicadoras.

Isso significa que a validação de bandeira tem duas camadas: (1) a entrada é sintaticamente dois codepoints de Regional Indicator, e (2) o par alpha-2 resultante corresponde a um país ISO 3166-1 reconhecido? Uma string pode passar no primeiro teste e falhar no segundo — combinações como 🇽🇽 (XX) são sequências bem formadas mas renderizam como as duas letras cruas porque nenhum país tem esse código.

O bloco Regional Indicator: U+1F1E6 a U+1F1FF

O Unicode reserva 26 codepoints no Supplementary Multilingual Plane para os Regional Indicators:

  • U+1F1E6 = 🇦, U+1F1E7 = 🇧, U+1F1E8 = 🇨, ... U+1F1FF = 🇿
  • Cada indicador tem 4 bytes em UTF-8 — um emoji de bandeira é portanto 8 bytes, o dobro de um emoji básico.
  • String.length em JavaScript devolve 4 para uma única bandeira (dois pares de surrogate), não 1.
  • Para contar bandeiras corretamente use o protocolo de iterador: [...'🇧🇷'].length === 2, depois agrupe em pares.

A regex de validação com o flag Unicode é direta:

const flagRegex = /^[\u{1F1E6}-\u{1F1FF}]{2}$/u

function ehBandeira(str) {
  if (!flagRegex.test(str)) return false
  const chars = [...str]
  const a = chars[0].codePointAt(0) - 0x1F1E6
  const b = chars[1].codePointAt(0) - 0x1F1E6
  const code = String.fromCharCode(65 + a, 65 + b)  // alpha-2
  return ISO_3166_1.has(code)
}

Subdivisões, bandeiras especiais e Tag Sequences

Um punhado de bandeiras foge do padrão Regional Indicator:

  • Inglaterra 🏴󠁧󠁢󠁥󠁮󠁧󠁿, Escócia 🏴󠁧󠁢󠁳󠁣󠁴󠁿, País de Gales 🏴󠁧󠁢󠁷󠁬󠁳󠁿 — usam Tag Sequence: bandeira preta base (U+1F3F4) mais caracteres Tag invisíveis soletrando o código ISO 3166-2 da subdivisão (gb-eng, gb-sct, gb-wls), terminado por U+E007F.
  • Bandeira pirata 🏴‍☠️ — bandeira preta + ZWJ (Zero-Width Joiner) + caveira e ossos cruzados.
  • Bandeira arco-íris 🏳️‍🌈 — bandeira branca + variation selector + ZWJ + arco-íris.
  • Bandeira trans 🏳️‍⚧️ — mesmo padrão ZWJ com o símbolo de gênero.

O total de bandeiras de país/território é aproximadamente 250, igual à lista ativa do ISO 3166-1. O Unicode CLDR (Common Locale Data Repository) fornece nomes de país localizados para cada — útil quando você quer mostrar "Brasil" ao lado de 🇧🇷 em UI portuguesa e "Brazil" em UI inglesa.

Inconsistências de plataforma e sensibilidades políticas

A renderização depende da plataforma e é politicamente carregada. A fonte de emoji da Apple inclui glifos de bandeira reais para todo país; o Noto Color Emoji do Google faz o mesmo. O Microsoft Windows historicamente renderizava as letras Regional Indicator cruas em vez de glifo — isso só mudou com o Windows 11. A bandeira de Taiwan 🇹🇼 é o exemplo canônico: no iOS o dispositivo a esconde quando a região do sistema é continente chinês; algumas builds de Android para o mercado chinês a omitem por inteiro. 🇽🇰 Kosovo foi adicionada tarde e ainda é inconsistente. 🇪🇺 União Europeia usa o código especial EU que é tecnicamente reservado, não atribuído.

Para aplicações isso significa: nunca assuma que o mesmo emoji de bandeira vai renderizar idêntico em todo dispositivo. Mostre o nome do país como fallback, sobretudo em contextos de acessibilidade onde leitores de tela podem anunciar apenas o código alpha-2.

Casos de uso em apps brasileiros

Emojis de bandeira aparecem em seletores de idioma (🇧🇷 / 🇺🇸 / 🇪🇸), country pickers em checkout de e-commerce, WhatsApp Status, bio de Instagram, badges de push notification e indicadores de região de CDN. A pior armadilha é usar uma bandeira para indicar um idioma em vez de um país — espanhol é falado em 21 países, e escolher 🇪🇸 em vez de 🇲🇽 é um sinal político que usuários percebem. O padrão seguro é rotular a opção por código de idioma (pt-BR, en-US) e colocar a bandeira ao lado como decoração, nunca como único identificador.

FAQ

Quantas bandeiras de país existem? Cerca de 250, igual ao ISO 3166-1. Subdivisões adicionam algumas via Tag Sequence (Inglaterra, Escócia, País de Gales, Texas em algumas fontes), e bandeiras especiais (pirata, arco-íris, trans) usam ZWJ sequences.

Por que meu código vê length 4 para 🇧🇷? Strings em JavaScript são UTF-16. Cada Regional Indicator está no plano suplementar e ocupa dois code units de surrogate, então a bandeira tem 4 code units UTF-16. Use [...str] ou str.codePointAt para contar caracteres reais.

Por que a bandeira de Taiwan some em alguns dispositivos? Apple e algumas builds de Android para o mercado chinês escondem 🇹🇼 quando a região do dispositivo está em continente chinês, por razões regulatórias. A sequência de codepoints subjacente ainda está nos dados — só o glifo renderizado muda.

Bandeiras de subdivisão são Tag Sequences? Sim. Inglaterra, Escócia e País de Gales usam a base de bandeira preta mais códigos ISO 3166-2 em caracteres Tag. A maioria das fontes renderiza como a bandeira regional; fontes antigas caem na bandeira preta crua.

Posso validar sem uma tabela ISO 3166? Só estruturalmente — dá para confirmar que a entrada é dois Regional Indicators, mas não dá para saber se o par codifica um país real sem a lista de lookup. Combinações como 🇽🇽 passam no regex mas não são bandeiras.

Ferramentas Relacionadas