Skl*_*vvz 38 c# regex globalization
虽然这看起来像一个微不足道的问题,但我很确定它不是:)
我需要验证来自世界各地的人的姓名和姓氏.我怎么能用正则表达式做到这一点?如果它只是英文版,我认为这会削减它:
^[a-z -']+$
Run Code Online (Sandbox Code Playgroud)
但是,我还需要支持这些案例:
有没有一种标准方法来验证我可以实现的这些字段,以确保我们的网站访问者有一个很好的经验,并可以在注册时实际使用他们的名字?
我会寻找类似于你可以在谷歌上找到的许多"电子邮件地址"正则表达式的东西.
Chr*_*ore 42
我其实不会打扰.
无论你想出什么样的正则表达式,我都可以在世界某个地方找到一个可以打破它的名字.
话虽这么说,你确实需要清理输入,以避免Little Bobby Tables问题.
Skl*_*vvz 16
我会试着给自己一个正确的答案:
名称中唯一允许的标点符号是句号,撇号和连字符.在角落案件清单中我没有看到任何其他案例.
关于数字,只有一个案例有8个.我想我可以安全地拒绝这个.
关于信件,任何信件都是有效的.
我也想要包括空间.
这将总结到这个正则表达式:
^[\p{L} \.'\-]+$
Run Code Online (Sandbox Code Playgroud)
这提出了一个问题,即撇号可以用作攻击向量.它应该编码.
所以验证代码应该是这样的(未经测试):
var name = nameParam.Trim();
if (!Regex.IsMatch(name, "^[\p{L} \.\-]+$"))
throw new ArgumentException("nameParam");
name = name.Replace("'", "'"); //' does not work in IE
Run Code Online (Sandbox Code Playgroud)
任何人都可以想到一个名称不应该通过此测试或可以通过的XSS或SQL注入的原因吗?
完整测试解决方案
using System;
using System.Text.RegularExpressions;
namespace test
{
class MainClass
{
public static void Main(string[] args)
{
var names = new string[]{"Hello World",
"John",
"João",
"???",
"???",
"??",
"??",
"??????",
"????????",
"?????????",
"???? ?????",
"?????????",
"??????",
"?",
"D'Addario",
"John-Doe",
"P.A.M.",
"' --",
"<xss>",
"\""
};
foreach (var nameParam in names)
{
Console.Write(nameParam+" ");
var name = nameParam.Trim();
if (!Regex.IsMatch(name, @"^[\p{L}\p{M}' \.\-]+$"))
{
Console.WriteLine("fail");
continue;
}
name = name.Replace("'", "'");
Console.WriteLine(name);
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
use*_*876 15
我只会允许所有内容(除了空字符串)并假设用户知道他的名字是什么.
有两种常见情况:
在情况(1)中,您可以允许所有字符,因为您正在检查纸质文档.
在情况(2)中,您也可以允许所有字符,因为"123 456"实际上并不比"Abc Def"更糟糕.
ksc*_*ott 13
我认为你最好用正则表达式排除你不想要的字符.试图获得每个变音,重音e,连字符等将是非常疯狂的.只是排除数字(但那么一个名为"George Forman the 4th"的人)和你知道你不想要的符号就像@#$%^或者你有什么.但即便如此,使用正则表达式只能保证输入与正则表达式匹配,它不会告诉你它是一个有效的名字
编辑后澄清这是试图阻止XSS: 名称字段上的正则表达式显然不会自行阻止XSS.但是,本文有一个关于过滤的部分,如果你想要走这条路线,这是一个起点.
http://tldp.org/HOWTO/Secure-Programs-HOWTO/cross-site-malicious-content.html
s/[\<\>\"\'\%\;\(\)\&\+]//g;
Run Code Online (Sandbox Code Playgroud)
顺便说一下,你打算只允许使用拉丁字母,还是打算尝试验证中文,阿拉伯语,印地语等?
正如其他人所说,甚至不尝试这样做.退后一步,问问自己你实际想要完成什么.然后尝试完成它,而不做任何关于人们姓名或者他们的意思的假设.
我认为这不是一个好主意.即使你找到一个合适的正则表达式(可能使用Unicode字符属性),这也不会阻止用户输入像John Doe,Max Mustermann(甚至有一个有这个名字的人),Abcde Fghijk或Ababa Bebebe这样的伪名字.
小智 5
您可以使用以下正则表达式代码验证由空格分隔的2个名称,并使用以下正则表达式代码:
^ [A-Za-zÀ-ú] + [A-Za-zÀ-ú] + $
[[:lower:]] = [a-zà-ú]
[[:upper:]] = [A-ZÀ-Ú]
[[:alpha:]] = [A-Za-zÀ-ú]
[[:alnum:]] = [A-Za-zÀ-ú0-9]