虽然这似乎是一个微不足道的问题,但我确信它不是:)
我需要验证来自世界各地的人的姓名和姓氏。我怎么能用正则表达式做到这一点?如果只是英国人,我认为这会削减它:
^[a-z -']+$
但是,我还需要支持这些案例:
是否有一种标准方法可以验证我可以实施的这些字段,以确保我们的网站访问者拥有良好的体验,并且在注册时可以使用他们的名字?
我会寻找类似于谷歌上可以找到的许多“电子邮件地址”正则表达式。
答案 0 :(得分:41)
答案 1 :(得分:18)
我会尝试自己给出正确答案:
名称中唯一允许使用的标点是句号,撇号和连字符。我没有在角落案件清单中看到任何其他案例。
关于数字,只有一个案例有8个。我想我可以放心地禁止它。
关于信件,任何信件都有效。
我也想要包括空间。
这将归结为这个正则表达式:
^[\p{L} \.'\-]+$
这提出了一个问题,即撇号可以用作攻击向量。它应该被编码。
因此验证码应该是这样的(未经测试):
var name = nameParam.Trim();
if (!Regex.IsMatch(name, "^[\p{L} \.\-]+$"))
throw new ArgumentException("nameParam");
name = name.Replace("'", "'"); //' does not work in IE
有人能想到名称不应该通过此测试或可以通过的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);
}
}
}
}
答案 2 :(得分:15)
我会允许所有内容(除了空字符串)并假设用户知道他的名字是什么。
有两种常见情况:
如果是(1),您可以允许所有字符,因为您正在检查纸质文档。
在情况(2)中,您也可以允许所有字符,因为“123 456”的假名并不比“Abc Def”更差。
答案 3 :(得分:10)
我认为你最好不要使用正则表达式排除你不想要的字符。试图获得每个变音,重音e,连字符等将是非常疯狂的。只是排除数字(但那么一个名为“George Forman the 4th”的人)和你知道你不想要的符号就像@#$%^或者你有什么。但即便如此,使用正则表达式只能保证输入与正则表达式匹配,它不会告诉你它是一个有效的名称
在澄清这是在试图阻止XSS后编辑: 名称字段上的正则表达式显然不会自行停止XSS。但是,本文有一个关于过滤的部分,如果你想走这条路,那么这是一个起点。
http://tldp.org/HOWTO/Secure-Programs-HOWTO/cross-site-malicious-content.html
s/[\<\>\"\'\%\;\(\)\&\+]//g;
答案 4 :(得分:6)
我认为这不是一个好主意。即使你找到一个合适的正则表达式(可能使用Unicode字符属性),这也不会阻止用户输入像 John Doe , Max Mustermann 这样的伪名称(甚至还有是一个有这个名字的人, Abcde Fghijk 或 Ababa Bebebe 。
答案 5 :(得分:6)
正如其他人所说,甚至不尝试来做到这一点。退后一步,问问自己你实际想要完成什么。然后尝试完成它,而不做任何关于人们姓名或者他们的意思的假设。
答案 6 :(得分:6)
您可以使用以下正则表达式代码验证由空格分隔的2个名称,并使用以下正则表达式代码:
^ [A-Za-zÀ-ú] + [A-Za-zÀ-ú] + $
[[:lower:]] = [a-zà-ú]
[[:upper:]] = [A-ZÀ-Ú]
[[:alpha:]] = [A-Za-zÀ-ú]
[[:alnum:]] = [A-Za-zÀ-ú0-9]
答案 7 :(得分:2)
由于可能的所有角落情况,验证名称之类的东西是一个非常困难的问题。
清理输入并让他们输入他们想要的任何名称,因为决定什么是有效名称和什么不是可能超出你正在做的范围;鉴于潜在的奇怪范围 - 合法的名称几乎是无限的。
如果他们想称自己为Tricyclopltz ^ 2-Glockenschpiel,那就是他们的问题,而不是你的问题。
答案 8 :(得分:2)
一个非常有争议的话题,我似乎在这里偶然发现了。然而,有时候在通行证上亲爱的小桌子并将小罗伯特连同他的分号和SQL注释行送到校长办公室是很好的。
VB.NET中的这个REGEX包括常规字母字符和各种欧洲字符。然而,可怜的老詹姆斯·麦克里斯坦 - 史密斯三世将不得不输入他的血统作为吉姆三世。
<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}\']+$">
答案 9 :(得分:0)
步骤:
去除重音:
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();
}
答案 10 :(得分:0)
此代码对我来说非常适合JavaScript ^ [a-zA-Z] + [\ s |-]?[a-zA-Z] + [\ s |-]?[a-zA-Z] + $
这是方法:
function isVallidName(name) {
var found = name.search(/^[a-zA-Z]+[\s|-]?[a-zA-Z]+[\s|-]?[a-zA-Z]+$/);
if(found > -1) {
return true;
}
else {
return false;
}
}
答案 11 :(得分:-1)
这有点帮助:
^[a-zA-Z]'?([a-zA-Z]|\.| |-)+$
答案 12 :(得分:-2)
这个应该有效
^([A-Z]{1}+[a-z\-\.\']*+[\s]?)*
如果需要,可以添加一些特殊字符。