Possible Duplicate:
A comprehensive regex for phone number validation可能重复:用于电话号码验证的综合正则表达式
I have an unformatted phone number (guaranteed to be 10 digits) and an unformatted extension (could be null, blank or any number of numbers). I need to put them together into a "friendly" string. I thought I'd concatenate them, then format the concatenation using a Regex.Replace. Here's the unit test I'm using to try various regexes before I plug one in:
我有一个未格式化的电话号码(保证是10位数)和未格式化的扩展名(可以是空,空白或任意数量的数字)。我需要将它们组合成一个“友好”的字符串。我以为我会连接它们,然后使用Regex.Replace格式化连接。这是我插入之前尝试各种正则表达式的单元测试:
[Test, Ignore("Sandbox, does not test production code")]
public void TestPhoneRegex()
{
string number = "1234567890";
string extension = "";
var formattedContactNumber =
Regex.Replace("{0} x{1}".FormatWith(number, extension),
@"^(\d{3})[ -]?(\d{3})[ -]?(\d{4})( x\d+)?",
@"$1-$2-$3$4");
Debug.WriteLine("{0} x{1}".FormatWith(number, extension));
Debug.WriteLine(formattedContactNumber);
Assert.AreEqual("123-456-7890", formattedContactNumber);
}
The expected formatted string is the formatted phone number, without the "x" and extension. However, the last capture group is matching the "x" with or without a number behind it, so instead of "123-456-7890" I get "123-456-7890 x". This is the last bit of development that needs to be tied down before a release. Help?
预期的格式化字符串是格式化的电话号码,没有“x”和扩展名。但是,最后一个捕获组匹配“x”有或没有数字,因此代替“123-456-7890”我得到“123-456-7890 x”。这是在发布之前需要关联的最后一点开发。帮帮我?
3 个解决方案
#1
2
x isn't matched by your regex, so it isn't replaced put of the string. Try this regex instead:
x与正则表达式不匹配,因此不会替换字符串的put。试试这个正则表达式:
@"^(\d{3})[ -]?(\d{3})[ -]?(\d{4}) x(\d*)
In the new regex x
isn't optional - it will always be there according to your code (If you do want it to be optional you can use ?x?(\d*)
). Also, we're using \d*
, so make sure the last group will always match, even when it's empty.
在新的正则表达式中x不是可选的 - 它将始终根据您的代码存在(如果您希望它是可选的,您可以使用?x?(\ d *))。此外,我们正在使用\ d *,因此请确保最后一组始终匹配,即使它是空的。
#2
10
I love regular expressions, don't get me wrong, but this does not seem like a useful area to apply them. All you are doing is adding dashes to a string of 10 numbers then adding an optional "x" followed by an extension. Simpler is better.
我喜欢正则表达式,不要误会我的意思,但这似乎不适合应用它们。您所做的就是将破折号添加到10个数字的字符串中,然后添加一个可选的“x”,后跟一个扩展名。更简单更好。
public static String beautifyPhoneNumber(String number, String extension)
{
String beautifulNumber = number.Substring(0, 3) + "-" +
number.Substring(3, 3) + "-" +
number.Substring(6, 4);
if (!String.IsNullOrEmpty(extension))
{
beautifulNumber += " x" + extension;
}
return beautifulNumber;
}
#3
2
This is maybe not a direct answer to your question, but possibly helpful... We use this pattern:
这可能不是你问题的直接答案,但可能有用...我们使用这种模式:
public const string NorthAmericanPhonePattern = @"^(\+?(?<NatCode>1)\s*[-\/\.]?)?(\((?<AreaCode>\d{3})\)|(?<AreaCode>\d{3}))\s*[-\/\.]?\s*(?<Number1>\d{3})\s*[-\/\.]?\s*(?<Number2>\d{4})\s*(([xX]|[eE][xX][tT])\.?\s*(?<Ext>\d+))*$";
And then reformat with:
然后重新格式化:
private static string PhoneNumberMatchEvaluator(Match match)
{
// Format to north american style phone numbers "0 (000) 000-0000"
// OR "(000) 000-0000"
Debug.Assert(match.Success);
if (match.Groups["NatCode"].Success)
{
return match.Result("${NatCode} (${AreaCode}) ${Number1}-${Number2}");
}
else
{
return match.Result("(${AreaCode}) ${Number1}-${Number2}");
}
}
private static string FormatPhoneNumber(string phoneNumber)
{
var regex = new Regex(NorthAmericanPhonePattern, RegexOptions.IgnoreCase);
return regex.Replace(phoneNumber, new MatchEvaluator(PhoneNumberMatchEvaluator));
}
Note: In our case we have included the national code if they did, you could easily take that out. We have also not included the extension in there - as we shift it out and put into a different field if we find it.
注意:在我们的案例中,我们已经包含了国家代码,如果他们这样做了,您可以轻松地将其取出。我们还没有将扩展包括在那里 - 因为我们将它移出并在我们发现它时进入不同的领域。
#1
2
x isn't matched by your regex, so it isn't replaced put of the string. Try this regex instead:
x与正则表达式不匹配,因此不会替换字符串的put。试试这个正则表达式:
@"^(\d{3})[ -]?(\d{3})[ -]?(\d{4}) x(\d*)
In the new regex x
isn't optional - it will always be there according to your code (If you do want it to be optional you can use ?x?(\d*)
). Also, we're using \d*
, so make sure the last group will always match, even when it's empty.
在新的正则表达式中x不是可选的 - 它将始终根据您的代码存在(如果您希望它是可选的,您可以使用?x?(\ d *))。此外,我们正在使用\ d *,因此请确保最后一组始终匹配,即使它是空的。
#2
10
I love regular expressions, don't get me wrong, but this does not seem like a useful area to apply them. All you are doing is adding dashes to a string of 10 numbers then adding an optional "x" followed by an extension. Simpler is better.
我喜欢正则表达式,不要误会我的意思,但这似乎不适合应用它们。您所做的就是将破折号添加到10个数字的字符串中,然后添加一个可选的“x”,后跟一个扩展名。更简单更好。
public static String beautifyPhoneNumber(String number, String extension)
{
String beautifulNumber = number.Substring(0, 3) + "-" +
number.Substring(3, 3) + "-" +
number.Substring(6, 4);
if (!String.IsNullOrEmpty(extension))
{
beautifulNumber += " x" + extension;
}
return beautifulNumber;
}
#3
2
This is maybe not a direct answer to your question, but possibly helpful... We use this pattern:
这可能不是你问题的直接答案,但可能有用...我们使用这种模式:
public const string NorthAmericanPhonePattern = @"^(\+?(?<NatCode>1)\s*[-\/\.]?)?(\((?<AreaCode>\d{3})\)|(?<AreaCode>\d{3}))\s*[-\/\.]?\s*(?<Number1>\d{3})\s*[-\/\.]?\s*(?<Number2>\d{4})\s*(([xX]|[eE][xX][tT])\.?\s*(?<Ext>\d+))*$";
And then reformat with:
然后重新格式化:
private static string PhoneNumberMatchEvaluator(Match match)
{
// Format to north american style phone numbers "0 (000) 000-0000"
// OR "(000) 000-0000"
Debug.Assert(match.Success);
if (match.Groups["NatCode"].Success)
{
return match.Result("${NatCode} (${AreaCode}) ${Number1}-${Number2}");
}
else
{
return match.Result("(${AreaCode}) ${Number1}-${Number2}");
}
}
private static string FormatPhoneNumber(string phoneNumber)
{
var regex = new Regex(NorthAmericanPhonePattern, RegexOptions.IgnoreCase);
return regex.Replace(phoneNumber, new MatchEvaluator(PhoneNumberMatchEvaluator));
}
Note: In our case we have included the national code if they did, you could easily take that out. We have also not included the extension in there - as we shift it out and put into a different field if we find it.
注意:在我们的案例中,我们已经包含了国家代码,如果他们这样做了,您可以轻松地将其取出。我们还没有将扩展包括在那里 - 因为我们将它移出并在我们发现它时进入不同的领域。