用于validation名字和姓氏的正则expression式?
虽然这似乎是一个微不足道的问题,但我确定它不是:)
我需要validation来自世界各地的人的姓名。 我如何用正则expression式来做到这一点? 如果只是英文的话,我认为这会削减它:
^[az -']+$
不过,我也需要支持这些情况:
- 其他标点符号,因为他们可能会在不同的国家使用(不知道哪个,但也许你做!)
- 不同的Unicode字母集(重音字母,希腊语,日语,中文等)
- 没有数字或符号或不必要的标点或符文等。
有没有一个标准的方式来validation这些领域,我可以执行,以确保我们的网站访问者有一个很好的经验,可以真正使用他们的名字时注册?
我会寻找类似于你可以在谷歌find许多“电子邮件地址”正则expression式。
我其实不会打扰。
无论你想出什么样的正则expression式,我都能在世界的某个地方find一个能打破它的名字。
这就是说,你需要清理input,以避免小鲍比表问题。
我会尽力自己给出一个正确的答案:
在名称中应该允许的唯一标点是句号,撇号和连字符。 我没有看到任何其他案件在angular落案件名单。
关于数字,只有一个8的情况。我想我可以放心地拒绝。
关于字母,任何字母都是有效的。
我也想包括空间。
这将总结到这个正则expression式:
^[\p{L} \.'\-]+$
这提出了一个问题,即撇号可以用作攻击vector。 它应该被编码。
所以validation码应该是这样的(未经testing):
var name = nameParam.Trim(); if (!Regex.IsMatch(name, "^[\p{L} \.\-]+$")) throw new ArgumentException("nameParam"); name = name.Replace("'", "'"); //' does not work in IE
任何人都可以想到一个名称不应该通过这个testing或XSS或SQL注入可以通过的原因吗?
完成testing解决scheme
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", "PAM", "' --", "<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); } } } }
我只是允许一切(除了一个空string),并假设用户知道他的名字是什么。
有两种常见的情况:
- 您关心的是名称是否准确,并且是针对真实的纸质护照或其他身份证件或信用卡进行validation。
- 您不会太在意,用户无论如何都可以注册为“Fred Smith”(或“Jane Doe”)。
在情况(1)中,您可以允许所有字符,因为您正在检查纸质文档。
在(2)的情况下,你可以允许所有的字符,因为“123 456”实际上并不比“Abc Def”更坏。
我想你会更好, 排除你不想用正则expression式的字符。 试图让每一个变音,重音e,连字符等将是相当疯狂的。 只是排除数字(但那么一个名叫“乔治·福曼第四”的人又如何?),你知道你不想要的符号像@#$%^或者你有什么。 但即使如此,使用正则expression式只会保证input匹配的正则expression式,它不会告诉你,这是一个有效的名称
编辑之后澄清,这是试图阻止XSS:在名称字段的正则expression式显然不会停止自己的XSS。 不过,如果你想要走这条路线,这篇文章有一个关于过滤的部分,这是一个起点。
http://tldp.org/HOWTO/Secure-Programs-HOWTO/cross-site-malicious-content.html
s/[\<\>\"\'\%\;\(\)\&\+]//g;
我不认为这是一个好主意。 即使你find一个合适的正则expression式(可能使用Unicode字符属性),这也不会阻止用户input像John Doe , Max Mustermann这样的伪名字(甚至有这个名字的人), Abcde Fghijk或者Ababa Bebebe 。
您可以使用以下正则expression式代码来validation由以下正则expression式代码分隔的2个名称:
^ [A-Za-zÀ-ú] + [A-Za-zÀ-ú] + $
或者只是使用:
[[:lower:]] = [a-zà-ú]
[[:upper:]] = [A-ZÀ-Ú]
[[:alpha:]] = [A-Za-zÀ-ú]
[[:alnum:]] = [A-Za-zÀ-ú0-9]
顺便说一句,你打算只允许拉丁字母,还是你也计划尝试validation中文,阿拉伯文,印度文等?
正如其他人所说,甚至不要尝试这样做。 退后一步,问问你自己究竟在做什么。 然后尝试做到这一点,而不要假设人们的名字是什么,或者是什么意思。
由于所有可能的angular落情况,validation类似名称的东西是一个非常困难的问题。
angular落案件
- 这里有任何东西
对input进行消毒,让他们input任何他们想要的名字,因为决定什么是有效的名字,什么不是,可能超出你所做的任何事情的范围。 考虑到潜在的奇怪范围 – 法定名称几乎是无限的。
如果他们想自称为三轮车,那么这就是他们的问题,而不是你的问题。
我似乎在这里偶然发现了一个颇有争议的话题。 然而,有时候在通行证里面亲爱的小桌子也不错,把小罗伯特和他的分号和SQL注释一起送给校长办公室。
VB.NET中的REGEX包含常规字母字符和各种旋转的欧洲字符。 然而,第三名可怜的老詹姆斯·麦克里斯坦 – 史密斯(Jim Mc'Tristan-Smythe)将不得不把他的血统input为第三吉姆。
<asp:RegularExpressionValidator ID="RegExValid1" Runat="server" ErrorMessage="ERROR: Please enter a valid surname<br/>" SetFocusOnError="true" Display="Dynamic" ControlToValidate="txtSurname" ValidationGroup="MandatoryContent" ValidationExpression="^[A-Za-z'\-\p{L}\p{Zs}\p{Lu}\p{Ll}\']+$">
这有点帮助:
^[a-zA-Z]'?([a-zA-Z]|\.| |-)+$
这个应该工作^([AZ]{1}+[az\-\.\']*+[\s]?)*
添加一些特殊字符,如果你需要它们。
脚步:
- 首先删除所有的口音
- 应用正则expression式
去除口音:
private static string RemoveAccents(string s) { s = s.Normalize(NormalizationForm.FormD); StringBuilder sb = new StringBuilder(); for (int i = 0; i < s.Length; i++) { if (CharUnicodeInfo.GetUnicodeCategory(s[i]) != UnicodeCategory.NonSpacingMark) sb.Append(s[i]); } return sb.ToString(); }