PHP Regex para nomes humanos
Pergunta
eu correr em um pouco de um problema com um Regex Eu estou usando para nomes de seres humanos.
$rexName = '/^[a-z' -]$/i';
Suponha que um usuário com o nome de Jürgen deseja registrar? Ou Bob? Isso é muito comum na Europa. Existe uma notação especial para isso?
EDIT :, jogou apenas o nome Jürgen contra um criador regex, e divide a palavra-se na letra u ...
http://www.txt2re.com/ index.php3? s = J% FCrgen + Blalock & submit = Mostrar + Jogos
EDIT2:? Allright, desde a verificação de tais coisas específicas é difícil, por que não usar um regex que simplesmente verifica se há caracteres ilegais
$rexSafety = "/^[^<,\"@/{}()*$%?=>:|;#]*$/i";
(agora quais destes podem realmente ser usado em qualquer atentado Hacker?)
Por exemplo. Isso permite 'e - sinais, mas você precisa de um; para fazê-lo funcionar em SQL, e esses serão stopped.Any outros personagens que são comumente usados ??para injeção HTML de ataques de SQL que eu estou perdendo?
Solução
Eu realmente dizer: não tente nomes Validate: um dia ou outro, seu código vai encontrar um nome que ele pensa que é "errado" ... E como você acha que um iria reagir quando um aplicativo lhe diz " seu nome não é válido "?
Dependendo do que você realmente deseja alcançar, você pode considerar o uso de algum tipo de lista negra / filtros, para excluir os "não-nomes" que você pensou sobre: ??será talvez deixar alguns "maus-nomes" passe, mas, ao menos, não deve impedir qualquer nome existente de acessar a sua aplicação.
Aqui estão alguns exemplos de regras que vêm à mente:
- nenhum número
- nenhum caráter especial, como
"~{()}@^$%?;:/*§£ø
e provavelmente alguns outros - não mais que 3 espaços?
- nenhum dos "admin", "apoio", "moderador", "teste", e algumas outras não-nomes óbvios que as pessoas tendem a usar quando não deseja digitar seu nome real ...
- (mas, se eles não querem dar-lhe seu nome, a sua ainda não vai, mesmo se você proibi-los de digitar algumas letras aleatórias, eles poderiam simplesmente usar um nome real ... O que não é deles)
Sim, esta não é perfeito; e sim, ele vai deixar alguns não-nomes passar ... Mas é provavelmente muito melhor para sua aplicação do que dizer a alguém "seu nome está errado" (sim, eu insisto ^^)
E, para responder a um comentário que deixou sob uma outra resposta:
Eu poderia simplesmente proibir a maioria comando caracteres para injeção SQL e XSS ataques,
Sobre SQL Injection, você deve escapar de seus dados antes de enviar aqueles à base de dados; e, se você sempre escapar esses dados (! você deve), você não precisa se preocupar com o que os usuários podem entrada ou não:. como ele escapou, sempre, não há risco para você
Mesmo sobre XSS: como você sempre escapar de seus dados quando ouputting-lo (! Você deve), não há risco de injecção; -)
EDIT: se você só usar esse regex assim, ele não vai funcionar muito bem:
O código a seguir:
$rexSafety = "/^[^<,\"@/{}()*$%?=>:|;#]*$/i";
if (preg_match($rexSafety, 'martin')) {
var_dump('bad name');
} else {
var_dump('ok');
}
Será que você obtenha, pelo menos, um aviso:
Warning: preg_match() [function.preg-match]: Unknown modifier '{'
Você deve escapar, pelo menos, alguns desses caracteres especiais; Eu vou deixar você cavar Padrões PCRE para mais informações (há é realmente um monte de saber sobre PCRE / regex; e eu não vou ser capaz de explicar tudo)
Se você realmente quiser verificar que nenhum desses personagens está dentro de uma determinada peça de dados, você pode acabar com algo assim:
$rexSafety = "/[\^<,\"@\/\{\}\(\)\*\$%\?=>:\|;#]+/i";
if (preg_match($rexSafety, 'martin')) {
var_dump('bad name');
} else {
var_dump('ok');
}
(Esta é uma proposta rápida e suja, que tem de ser refinado!)
Este diz "OK" (bem, eu definitivamente espero que o meu próprio nome é ok!)
E o mesmo exemplo com alguns especiais caracteres, como este:
$rexSafety = "/[\^<,\"@\/\{\}\(\)\*\$%\?=>:\|;#]+/i";
if (preg_match($rexSafety, 'ma{rtin')) {
var_dump('bad name');
} else {
var_dump('ok');
}
Será que dizer "mau nome"
Mas, por favor, note que eu tenho não totalmente testado isso, e provavelmente precisa de mais trabalho! Não use este em seu site a menos que você testou-o com muito cuidado!
Também nota que uma única citação pode ser útil quando se tenta fazer uma injeção SQL ... Mas é provavelmente um personagem que é legal em alguns nomes ... Assim, apenas excluindo alguns caracteres pode não ser suficiente; -)
Outras dicas
implementação PCRE do PHP suportes propriedades de caracteres Unicode que abrangem um conjunto maior de caracteres. Então, você poderia usar uma combinação de \p{L}
(caracteres carta), \p{P}
(caracteres de pontuação) e \p{Zs}
(caracteres espaço separador):
/^[\p{L}\p{P}\p{Zs}]+$/
Mas pode haver caracteres que não são abrangidos por estas categorias de caracteres, enquanto pode haver alguma incluído que você não quer ser permitido.
Então, eu conselho você contra o uso de expressões regulares em um dado com uma vaga gama de valores como o nome de uma pessoa real tal.
Editar Como você editou sua pergunta e agora ver que você só quer evitar certos ataques de injeção de código:. Você deve melhor escapar esses personagens, em vez de rejeitá-los como uma potencial tentativa de ataque
Use mysql_real_escape_string
ou instruções preparadas para consultas SQL, htmlspecialchars
para a saída de HTML e outras funções apropriadas para outros idiomas.
Isso é um problema sem solução geral fácil. A coisa é que você realmente não pode prever quais caracteres um nome poderia conter. Provavelmente, a melhor solução é definir uma máscara de caráter negativo para excluir alguns caracteres especiais que você realmente não quer acabar em um nome.
Você pode fazer isso usando:
$ regexp = "/ ^ [ ^
Se você está tentando analisar distante um nome humano em PHP, eu recomment Keith Beckman roteiro nameparse.php .