M · UDF
fnNuvemDePalavras
Limpa um texto em português para nuvem de palavras: remove pontuação e palavras sem valor analítico (stopwords) e preserva as negações.
Sintaxe
fnNuvemDePalavras(texto as nullable text) as nullable textArgumentos
| Nome | Tipo | Obrigatório | Descrição |
|---|---|---|---|
| texto | nullable text | Sim | Texto livre (comentário, pesquisa, descrição). |
Retorno
nullable text
Código completo
let
fnNuvemDePalavras = (texto as nullable text) as nullable text =>
let
// Pontuação e espaços viram delimitadores num único Text.SplitAny; o hífen fica dentro da palavra
vDelimitadores =
"!.:;,?@#$%^&*()[]{}\/_+=<>|""“”…'´`~–—"
& " #(tab)#(cr)#(lf)#(00A0)",
// Negações NÃO são stopwords: elas se juntam à palavra seguinte
vNegacoes = {"não", "nao", "nunca", "nem", "jamais"},
// Amplie a lista conforme o assunto analisado
vStopWords = {
"a", "à", "às", "ao", "aos", "as", "o", "os", "um", "uma", "uns", "umas",
"de", "da", "das", "do", "dos", "em", "na", "nas", "no", "nos", "num", "numa",
"para", "pra", "pro", "pelo", "pela", "pelos", "pelas", "por", "com", "sem", "sobre", "entre",
"e", "ou", "mas", "porém", "porque", "pq", "que", "q", "se", "como", "também", "tb", "tbm", "então", "sim",
"é", "foi", "fui", "ser", "sido", "será", "são", "era", "eram", "está", "estão", "estou", "estava", "estavam",
"ter", "tem", "têm", "tenho", "tive", "teve", "tinha", "há", "havia",
"eu", "me", "mim", "você", "vc", "ele", "ela", "eles", "elas", "nós", "lhe", "lhes",
"seu", "sua", "seus", "suas", "meu", "minha", "meus", "minhas", "teu", "tua", "teus", "tuas",
"esse", "essa", "esses", "essas", "este", "esta", "estes", "estas",
"aquele", "aquela", "aqueles", "aquelas", "isto", "isso", "aquilo",
"muito", "muita", "muitos", "muitas", "mais", "bem", "já", "só", "ainda", "tudo", "todo", "toda"
},
vTokens = List.Select(
Text.SplitAny(Text.Lower(texto), vDelimitadores),
each _ <> "" and _ <> "-" and not List.Contains(vStopWords, _)
),
// "não recomendo" → "não-recomendo"; negação no fim do texto fica sozinha
vEstado = List.Accumulate(
vTokens,
[Lista = {}, Pendente = null],
(estado, palavra) =>
if List.Contains(vNegacoes, palavra) then
[Lista = estado[Lista],
Pendente = if estado[Pendente] = null then palavra else estado[Pendente] & "-" & palavra]
else
[Lista = estado[Lista] & {if estado[Pendente] = null then palavra else estado[Pendente] & "-" & palavra},
Pendente = null]
),
vPalavras = if vEstado[Pendente] = null then vEstado[Lista] else vEstado[Lista] & {vEstado[Pendente]}
in
if texto = null then null else Text.Combine(vPalavras, " "),
fnNuvemDePalavrasTipo = type function (
texto as (type nullable text meta [
Documentation.FieldCaption = "Texto",
Documentation.FieldDescription = "Comentário livre (ex.: feedback de pesquisa). Null retorna null."
])
) as nullable text meta [
Documentation.Name = "fnNuvemDePalavras",
Documentation.Description = "Limpa um texto para nuvem de palavras, preservando negações.",
Documentation.LongDescription = "Converte para minúsculas, quebra por pontuação e espaços, remove artigos, preposições, pronomes, verbos auxiliares e intensificadores do português e junta negações (não, nunca, nem, jamais) à palavra seguinte com hífen, para que 'não recomendo' não vire 'recomendo'. A lista vStopWords pode ser ampliada.",
Documentation.Category = "Texto",
Documentation.Author = "Paulo André Jesus",
Documentation.Version = "3.0",
Documentation.Examples = {
[Description = "Negação preservada", Code = "fnNuvemDePalavras(""Não recomendo, tive uma experiência negativa."")", Result = """não-recomendo experiência negativa"""],
[Description = "Negação após stopword", Code = "fnNuvemDePalavras(""Não estou satisfeito com o suporte."")", Result = """não-satisfeito suporte"""],
[Description = "Só stopwords", Code = "fnNuvemDePalavras(""O que é isso?"")", Result = """"""]
}
]
in
Value.ReplaceType(fnNuvemDePalavras, fnNuvemDePalavrasTipo)Exemplos
fnNuvemDePalavras("Não recomendo, tive uma experiência negativa.")
// "não-recomendo experiência negativa"
fnNuvemDePalavras("Não estou satisfeito com o suporte.")
// "não-satisfeito suporte"
fnNuvemDePalavras("O que é isso?")
// ""Dicas e observações
⚠️ Na versão 2.0, "não" era stopword: "Não recomendo" virava "recomendo" e a nuvem dos detratores mostrava elogios. Num modelo NPS real, 595 comentários (186 de detratores) perdiam a negação. 💡 A negação espera a próxima palavra que não é stopword: "não estou satisfeito" vira "não-satisfeito". 💡 O hífen mantém a expressão como um único termo no visual de nuvem; hífen dentro da palavra também é mantido (guarda-chuva). 💡 Para contar termos por conceito, cliente ou período, expanda a saída numa tabela com uma linha por palavra (Text.Split + Table.ExpandListColumn). 💡 A saída vem em minúsculas. Amplie vStopWords com termos do assunto analisado.