尽管这似乎是一个琐碎的问题,但我很确定这不是一个小问题:)
我需要验证来自世界各地的人的名字和姓氏。想象一下一个巨大的名字和姓氏的缩略语列表,在这里我需要尽可能地删除我发现的所有碎片。我该如何使用正则表达式呢?如果只是英语,那我想这会减少它:
^[a-z -']+$
但是,我还需要支持以下情况:
我可以执行一些标准方法来验证这些字段,以确保我们的网站用户拥有丰富的经验,并且可以在列表中注册时实际 使用其名称 吗?
我会寻找与您可以在Google上找到的许多“电子邮件地址”正则表达式类似的东西。
我会尝试自己给出一个正确的答案:
名称中唯一应允许的标点是句号,撇号和连字符。在角落案例列表中,我还没有看到其他案例。
关于数字,只有一个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); } } } }