encontrar ocorrência de um conjunto de palavras
-
22-07-2019 - |
Pergunta
Eu tenho um padrão com uma pequena lista de palavras que são ilegais para usar como apelidos criados em uma variável de modelo como este:
$pattern = webmaster|admin|webadmin|sysadmin
Usando preg_match
, como posso conseguir para que nicknames com essas palavras são proibidas, mas registrar algo como "admin2
" ou "thesysadmin
" é permitido?
Esta é a expressão que eu tenho até agora:
preg_match('/^['.$pattern.']/i','admin');
// não deve ser permitido
Nota:. Usando um \b
não ajudou muito
Solução
O que sobre não usar regex em tudo?
E trabalhar com explode
e in_array
?
Por exemplo, este faria:
$pattern = 'webmaster|admin|webadmin|sysadmin';
$forbidden_words = explode('|', $pattern);
Ela explode o seu padrão em uma matriz, usando | como separador.
E esta:
$word = 'admin';
if (in_array($word, $forbidden_words)) {
echo "<p>$word is not OK</p>";
} else {
echo "<p>$word is OK</p>";
}
vai te
admin is not OK
Considerando que esta (mesmo código, apenas a palavra muda) :
$word = 'admin2';
if (in_array($word, $forbidden_words)) {
echo "<p>$word is not OK</p>";
} else {
echo "<p>$word is OK</p>";
}
vai te
admin2 is OK
Desta forma, não há necessidade de se preocupar em encontrar o regex direita, para igualar-palavras cheias: ele só vai coincidir com palavras exatas; -)
Editar: um problema pode ser que a comparação será maiúsculas de minúsculas :-(
Trabalho com tudo em letras minúsculas vai ajudar com isso:
$pattern = strtolower('webmaster|admin|webadmin|sysadmin'); // just to be sure ;-)
$forbidden_words = explode('|', $pattern);
$word = 'aDMin';
if (in_array(strtolower($word), $forbidden_words)) {
echo "<p>$word is not OK</p>";
} else {
echo "<p>$word is OK</p>";
}
vai te:
aDMin is not OK
(vi a bandeira 'i
' na regex somente após a postar minha resposta, por isso, teve de editá-lo)
Editar 2: e, se você realmente quer fazer isso com um regex, você precisa saber que:
- marcas
^
o início da cadeia - e
$
marca o fim da cadeia
Assim, algo como isso deve fazer:
$pattern = 'webmaster|admin|webadmin|sysadmin';
$word = 'admin';
if (preg_match('#^(' . $pattern . ')$#i', $word)) {
echo "<p>$word is not OK</p>";
} else {
echo "<p>$word is OK</p>";
}
$word = 'admin2';
if (preg_match('#^(' . $pattern . ')$#i', $word)) {
echo "<p>$word is not OK</p>";
} else {
echo "<p>$word is OK</p>";
}
Parênteses provavelmente não são necessários, mas eu gosto de usá-los, para isolar o que eu queria.
E, você vai ter o mesmo tipo de saída:
admin is not OK
admin2 is OK
Você provavelmente não quer usar [
e ]
: eles significam "qualquer caractere que está entre nós", e não "toda a cadeia que está entre nós"
E, como referência: manual do preg sintaxe ; -)
Outras dicas
Assim, as palavras proibidas pode ser parte de seu nome de usuário, mas não a coisa toda?
Em .NET, o padrão seria:
Allowed = Not RegEx.Match("admin", "^(webmaster|admin|webadmin|sysadmin)$")
O "^" corresponde ao início da cadeia, o "$" corresponde ao fim, por isso está à procura de uma correspondência exata em uma dessas palavras. Eu sou um pouco confuso sobre a sintaxe PHP correspondente.