我遇到了一个用于人类名字的正则表达式的问题。
$rexName = '/^[a-z' -]$/i';
假设名为Jürgen的用户希望注册?还是Böb?这在欧洲非常普遍。有没有特别的符号呢?
编辑:,只是把Jürgen的名字扔给了一个正则表达式的创造者,它把这个词分成了字母......http://www.txt2re.com/index.php3?s=J%FCrgen+Blalock&submit=Show+Matches
EDIT2:好的,因为检查这些特定的东西很难,为什么不使用只检查非法字符的正则表达式呢?
$rexSafety = "/^[^<,\"@/{}()*$%?=>:|;#]*$/i";
(现在哪些实际上可以用于任何黑客攻击?)
例如。这允许'和 - 标志,但你需要一个;使它在SQL中工作,那些将被停止。任何其他常用于HTML注入SQL攻击的字符,我都缺少?
答案 0 :(得分:21)
我真的会说:不要试图验证名称:有一天,你的代码会遇到一个它认为“错误”的名字......你觉得当应用程序告诉他时你会怎么回应? “你的名字无效”?
根据你真正想要实现的目标,你可以考虑使用某种黑名单/过滤器来排除你想到的“非名字”:它可能会让一些“坏名字”通过,但是,至少,它不应该阻止任何现有名称访问您的应用程序。
以下是一些可以想到的规则示例:
"~{()}@^$%?;:/*§£ø
,可能还有其他一些是的,这并不完美;是的,它会让一些非名字传递......但是对你的应用来说可能比说“你的名字错了”更好(是的,我坚持^^)
并且,回答你留下的评论:
我可以禁止最多的命令 SQL注入和XSS的字符 攻击,
关于SQL注入,您必须在将数据发送到数据库之前将其转义;并且,如果你总是逃避这些数据(你应该!),你不必关心用户可能输入的内容:因为它被转义,所以总是存在风险。
相同的XSS:因为你总是在输出数据时逃避你的数据(你应该!),没有注入的风险; - )
编辑:如果你只是使用那样的正则表达式,它将无法正常工作:
以下代码:
$rexSafety = "/^[^<,\"@/{}()*$%?=>:|;#]*$/i";
if (preg_match($rexSafety, 'martin')) {
var_dump('bad name');
} else {
var_dump('ok');
}
至少会给你一个警告:
Warning: preg_match() [function.preg-match]: Unknown modifier '{'
你必须逃脱至少一些特殊的角色;我会让你深入研究PCRE Patterns以获取更多信息(关于PCRE /正则表达式真的有很多了解;我将无法解释所有这些)
如果您确实想要检查这些字符中是否存在这些字符,那么最终可能会出现类似的情况:
$rexSafety = "/[\^<,\"@\/\{\}\(\)\*\$%\?=>:\|;#]+/i";
if (preg_match($rexSafety, 'martin')) {
var_dump('bad name');
} else {
var_dump('ok');
}
(这是一个快速而肮脏的主张,必须加以完善!)
这个人说“OK”(好吧,我肯定希望我自己的名字没问题!)
和一些特殊字符相同的例子,如下:
$rexSafety = "/[\^<,\"@\/\{\}\(\)\*\$%\?=>:\|;#]+/i";
if (preg_match($rexSafety, 'ma{rtin')) {
var_dump('bad name');
} else {
var_dump('ok');
}
会说“坏名声”
但请注意我不对此进行了全面测试,可能需要更多工作!除非您经过仔细测试,否则请勿在您的网站上使用此功能!
另请注意,在尝试执行SQL注入时,单引号可能会有所帮助......但它可能是某些名称中合法的字符...因此,仅排除某些字符可能是不够的; - )
答案 1 :(得分:6)
PHP’s PCRE implementation支持跨越更多字符的Unicode character properties。因此,您可以使用\p{L}
(字母字符),\p{P}
(标点字符)和\p{Zs}
(空格分隔符)的组合:
/^[\p{L}\p{P}\p{Zs}]+$/
但是可能会有这些字符类别未涵盖的字符,而可能包含一些您不希望被允许的字符。
因此,我建议您不要在数据上使用正则表达式,这些表达式具有如此模糊的值范围,例如真实姓名。
编辑在编辑问题时,现在看到您只想防止某些代码注入攻击:您应该更好地逃避这些角色,而不是将其作为潜在的攻击企图拒绝。
使用mysql_real_escape_string
或prepared statements进行SQL查询,使用htmlspecialchars
进行HTML输出,并使用其他语言的其他适当函数。
答案 2 :(得分:4)
这是一个没有简单通用解决方案的问题。问题是你真的无法预测名称可能包含的字符。可能最好的解决方案是定义一个负面的字符掩码,以排除一些你真的不希望以名字结尾的特殊字符。
您可以使用以下方式执行此操作:
$ regexp =“/ ^ [ ^ &lt;把不需要的字符放在这里&gt; ] + $ /
答案 3 :(得分:2)
如果您尝试在PHP中解析人名,我建议Keith Beckman's nameparse.php script。