Detectando Mensagens com Apenas Emojis em PHP
Introdução
Ao construir chatbots ou aplicações de mensagens, frequentemente você precisará detectar quando um usuário envia uma mensagem que contém apenas emojis. Isso é comum em cenários como:
- Reações a stories do Instagram - Usuários frequentemente respondem apenas com "❤️" ou "😂"
- Reações em chats - Respostas rápidas com emoji como "👍" ou "🔥"
- Filtragem de mensagens - Tratar mensagens apenas com emojis de forma diferente do texto
Neste artigo, vamos construir uma função simples em PHP para detectar mensagens que contêm apenas emojis usando expressões regulares.
O Desafio do Unicode
Emojis são mais complexos do que aparentam. O que parece ser um único emoji pode na verdade ser múltiplos caracteres Unicode combinados:
- Emojis básicos: Pontos de código únicos como 😀 (U+1F600)
- Modificadores de tom de pele: 👋🏽 é 👋 + 🏽 (tom de pele médio)
- Sequências ZWJ: 👨👩👧 é na verdade 👨 + ZWJ + 👩 + ZWJ + 👧
- Emojis de bandeiras: 🇧🇷 é formado por dois símbolos indicadores regionais
Essa complexidade significa que não podemos simplesmente verificar um único caractere—precisamos de um padrão regex que cubra todos os intervalos Unicode de emojis.
A Implementação
Aqui está uma implementação prática que lida com os emojis mais comuns:
/**
* Verifica se o texto contém apenas emojis e espaços em branco.
* Útil para detectar reações ou mensagens apenas com emojis.
*/
function isOnlyEmojis(?string $text): bool
{
if (!$text || trim($text) === '') {
return false;
}
// Remove todos os espaços em branco
$textWithoutWhitespace = preg_replace('/\s+/u', '', $text);
if ($textWithoutWhitespace === '') {
return false;
}
// Padrão regex Unicode para emojis
$emojiPattern = '/^[\x{1F600}-\x{1F64F}' . // Emoticons
'\x{1F300}-\x{1F5FF}' . // Símbolos e Pictogramas Diversos
'\x{1F680}-\x{1F6FF}' . // Transporte e Mapa
'\x{1F700}-\x{1F77F}' . // Símbolos Alquímicos
'\x{1F780}-\x{1F7FF}' . // Formas Geométricas Estendidas
'\x{1F800}-\x{1F8FF}' . // Setas Suplementares-C
'\x{1F900}-\x{1F9FF}' . // Símbolos e Pictogramas Suplementares
'\x{1FA00}-\x{1FA6F}' . // Símbolos de Xadrez
'\x{1FA70}-\x{1FAFF}' . // Símbolos e Pictogramas Estendidos-A
'\x{1F1E6}-\x{1F1FF}' . // Bandeiras (Símbolos Indicadores Regionais)
'\x{2600}-\x{26FF}' . // Símbolos diversos (sol, lua, estrelas)
'\x{2700}-\x{27BF}' . // Dingbats
'\x{2300}-\x{23FF}' . // Técnicos Diversos
'\x{2B50}\x{2B55}' . // Estrela e círculo
'\x{231A}\x{231B}' . // Relógio e ampulheta
'\x{2328}' . // Teclado
'\x{23CF}' . // Símbolo de ejetar
'\x{23E9}-\x{23F3}' . // Símbolos de controle de mídia
'\x{23F8}-\x{23FA}' . // Símbolos de controle de mídia
'\x{24C2}' . // M circulado
'\x{25AA}\x{25AB}' . // Quadrados pequenos
'\x{25B6}\x{25C0}' . // Botões de play
'\x{25FB}-\x{25FE}' . // Quadrados
'\x{2934}\x{2935}' . // Setas
'\x{2B05}-\x{2B07}' . // Setas
'\x{3030}' . // Traço ondulado
'\x{303D}' . // Marca de alternação de parte
'\x{3297}' . // Ideograma circulado de Parabéns
'\x{3299}' . // Ideograma circulado de Secreto
'\x{FE0F}' . // Seletor de Variação-16 (apresentação emoji)
'\x{200D}' . // Zero Width Joiner (para emojis combinados)
']+$/u';
return preg_match($emojiPattern, $textWithoutWhitespace) === 1;
}Exemplos de Uso
// Emojis básicos
isOnlyEmojis('😀'); // true
isOnlyEmojis('❤️🔥'); // true
isOnlyEmojis('👍👍👍'); // true
// Com espaços em branco (ainda válido)
isOnlyEmojis('😀 😂 🎉'); // true
// Emojis combinados (sequências ZWJ)
isOnlyEmojis('👨👩👧'); // true
isOnlyEmojis('👋🏽'); // true (modificador de tom de pele)
// Conteúdo misto (não é apenas emoji)
isOnlyEmojis('Olá 👋'); // false
isOnlyEmojis('Legal! 🔥'); // false
isOnlyEmojis('123'); // false
// Casos extremos
isOnlyEmojis(''); // false
isOnlyEmojis(null); // false
isOnlyEmojis(' '); // false (apenas espaços em branco)Entendendo os Intervalos Unicode
Vamos detalhar os principais intervalos Unicode no nosso padrão:
| Intervalo | Descrição | Exemplos |
|---|---|---|
1F600-1F64F | Emoticons | 😀 😂 😍 🙄 |
1F300-1F5FF | Símbolos e Pictogramas Diversos | 🌟 🎉 🔥 💡 |
1F680-1F6FF | Transporte e Mapa | 🚀 ✈️ 🏠 |
1F900-1F9FF | Símbolos Suplementares | 🤖 🦄 🧠 |
1F1E6-1F1FF | Indicadores Regionais | 🇺🇸 🇪🇸 🇧🇷 |
2600-26FF | Símbolos Diversos | ☀️ ⭐ ♥️ |
FE0F | Seletor de Variação | Faz símbolos de texto aparecerem como emoji |
200D | Zero Width Joiner | Conecta emojis (👨👩👧) |
Por que incluir FE0F e 200D?
O Seletor de Variação-16 (U+FE0F) diz ao sistema para renderizar um caractere como emoji. O Zero Width Joiner (U+200D) conecta múltiplos emojis em um emoji combinado, como emojis de família ou profissão.
Caso de Uso Prático: Reações em Chatbot
Veja como você pode usar isso em um contexto de chatbot:
function handleIncomingMessage(string $message): void
{
if (isOnlyEmojis($message)) {
// É uma reação! Trate de forma diferente
logReaction($message);
// Talvez não dispare uma resposta completa de IA para apenas "👍"
return;
}
// Processe como uma mensagem de texto normal
processTextMessage($message);
}Limitações
Esta abordagem baseada em regex tem algumas limitações:
- Novos emojis: O Unicode adiciona novos emojis regularmente. O padrão pode não cobrir as adições mais recentes.
- Alguns casos extremos: Certas combinações de emojis raramente usadas podem não ser detectadas.
- Performance: Para strings muito longas, regex pode ser mais lento que abordagens baseadas em bibliotecas.
Alternativa: Usando uma Biblioteca
Para detecção de emojis mais abrangente, considere usar uma biblioteca dedicada como p3k/emoji-detector:
composer require p3k/emoji-detectoruse Emoji\Detector;
$detector = new Detector();
$result = $detector->detect('Olá 👋 Mundo');
// Retorna array de emojis detectados com posiçõesA abordagem com biblioteca é mais robusta, mas adiciona uma dependência. Para verificações simples de "isso é apenas emoji?", a abordagem com regex é leve e suficiente.
Conclusão
Detectar mensagens com apenas emojis é útil para muitas aplicações de mensagens. Os pontos principais são:
- Emojis são complexos - Podem ser caracteres únicos ou combinações
- Use intervalos Unicode - Cubra os principais blocos de emoji no seu regex
- Não esqueça ZWJ e FE0F - Esses caracteres invisíveis são essenciais para emojis combinados
- Considere seu caso de uso - Regex simples funciona para a maioria dos casos; use uma biblioteca para necessidades avançadas
A abordagem com regex mostrada aqui lida com a grande maioria do uso real de emojis enquanto mantém seu código livre de dependências.

