我想知道在发送文本之前解析和验证手机号码的最佳做法是什么。我已经有了可行的代码,但我想找到更好的方法(我的上一个问题,这是我早期新年决议中编写质量更好的代码的一部分!)。
当用户输入表格上的号码时,我们非常宽容,他们可以输入“+44 123 4567890”,“00441234567890”,“0123456789”,“+ 44(0)123456789”,“ 012-345-6789“甚至”还没有电话“。
但是,要发送文本格式必须是44xxxxxxxxxx(这仅适用于英国手机),因此我们需要先解析并验证,然后再发送。下面是我现在的代码(C#,asp.net),如果有人对如何改进它有任何想法会很棒。
谢谢,
Annelie
private bool IsMobileNumberValid(string mobileNumber)
{
// parse the number
_mobileNumber = ParsedMobileNumber(mobileNumber);
// check if it's the right length
if (_mobileNumber.Length != 12)
{
return false;
}
// check if it contains non-numeric characters
if(!Regex.IsMatch(_mobileNumber, @"^[-+]?[0-9]*\.?[0-9]+$"))
{
return false;
}
return true;
}
private string ParsedMobileNumber(string number)
{
number = number.Replace("+", "");
number = number.Replace(".", "");
number = number.Replace(" ", "");
number = number.Replace("-", "");
number = number.Replace("/", "");
number = number.Replace("(", "");
number = number.Replace(")", "");
number = number.Trim(new char[] { '0' });
if (!number.StartsWith("44"))
{
number = "44" + number;
}
return number;
}
修改
这是我最终的结果:
private bool IsMobileNumberValid(string mobileNumber)
{
// remove all non-numeric characters
_mobileNumber = CleanNumber(mobileNumber);
// trim any leading zeros
_mobileNumber = _mobileNumber.TrimStart(new char[] { '0' });
// check for this in case they've entered 44 (0)xxxxxxxxx or similar
if (_mobileNumber.StartsWith("440"))
{
_mobileNumber = _mobileNumber.Remove(2, 1);
}
// add country code if they haven't entered it
if (!_mobileNumber.StartsWith("44"))
{
_mobileNumber = "44" + _mobileNumber;
}
// check if it's the right length
if (_mobileNumber.Length != 12)
{
return false;
}
return true;
}
private string CleanNumber(string phone)
{
Regex digitsOnly = new Regex(@"[^\d]");
return digitsOnly.Replace(phone, "");
}
答案 0 :(得分:2)
使用正则表达式删除任何非数字字符,而不是试图猜测一个人将如何输入他们的数字 - 这将删除所有的Replace()和Trim()方法,除非你真的需要修剪前导零
string CleanPhone(string phone)
{
Regex digitsOnly = new Regex(@"[^\d]");
return digitsOnly.Replace(phone, "");
}
或者,我建议您使用蒙版文本框来收集#(有许多可用选项)以仅允许数字输入,并以您想要的任何格式显示输入。这样您就可以保证收到的值都是数字字符。
答案 1 :(得分:1)
查看QAS,这是一个商业解决方案。
他们有电子邮件,电话和地址验证。
http://www.qas.com/phone-number-validation-web-service.htm
我们将他们的服务用于地址和电子邮件(而不是电话)并且对此感到满意。
答案 2 :(得分:0)
@annelie也许您可以将正则表达式更新为更强大的正则表达式。查看此网站here。它包含许多表达式,但我认为网站中前2个表达式中的一个应该适合您。
答案 3 :(得分:0)
public class PhoneNumber
{
public PhoneNumber(string value)
{
if (String.IsNullOrEmpty(value))
throw new ArgumentNullException("numberString", Properties.Resources.PhoneNumberIsNullOrEmpty);
var match = new Regex(@"\+(\w+) \((\w+)\) (\w+)", RegexOptions.Compiled).Match(value);
if (match.Success)
{
ushort countryCode = 0;
ushort localCode = 0;
int number = 0;
if (UInt16.TryParse(match.Result("$1"), out countryCode) &&
UInt16.TryParse(match.Result("$2"), out localCode) &&
Int32.TryParse(match.Result("$3"), out number))
{
this.CountryCode = countryCode;
this.LocalCode = localCode;
this.Number = number;
}
}
else
{
throw new ArgumentNullException("numberString", Properties.Resources.PhoneNumberInvalid);
}
}
public PhoneNumber(int countryCode, int localCode, int number)
{
if (countryCode == 0)
throw new ArgumentOutOfRangeException("countryCode", Properties.Resources.PhoneNumberIsNullOrEmpty);
else if (localCode == 0)
throw new ArgumentOutOfRangeException("localCode", Properties.Resources.PhoneNumberIsNullOrEmpty);
else if (number == 0)
throw new ArgumentOutOfRangeException("number", Properties.Resources.PhoneNumberIsNullOrEmpty);
this.CountryCode = countryCode;
this.LocalCode = localCode;
this.Number = number;
}
public int CountryCode { get; set; }
public int LocalCode { get; set; }
public int Number { get; set; }
public override string ToString()
{
return String.Format(System.Globalization.CultureInfo.CurrentCulture, "+{0} ({1}) {2}", CountryCode, LocalCode, Number);
}
public static bool Validate(string value)
{
return new Regex(@"\+\w+ \(\w+\) \w+", RegexOptions.Compiled).IsMatch(value);
}
public static bool Validate(string countryCode, string localCode, string number, out PhoneNumber phoneNumber)
{
var valid = false;
phoneNumber = null;
try
{
ushort uCountryCode = 0;
ushort uLocalCode = 0;
int iNumber = 0;
// match only if all three numbers have been parsed successfully
valid = UInt16.TryParse(countryCode, out uCountryCode) &&
UInt16.TryParse(localCode, out uLocalCode) &&
Int32.TryParse(number, out iNumber);
if (valid)
phoneNumber = new PhoneNumber(uCountryCode, uLocalCode, iNumber);
}
catch (ArgumentException)
{
// still not match
}
return valid;
}
}