Я пытаюсь создать функцию что форматы номера телефона США - надо надеяться, без цикличного выполнения через каждую цифру.
То, когда 10 цифр передаются всего, прекрасно. Как когда-либо, когда больше чем 10 цифр передаются в, я хочу Строку. Способ форматирования для добавления дополнительных цифр справа. Например:
То, когда 14 цифр передали в результате, должно быть: (444) 555-2222 x8888, Когда 12 цифр передали в результате, должен быть: (444) 555-2222 x88 и т.д. Однако то, что я получаю со своей текущей попыткой: Передача в 12 цифрах возвращает эту строку' ()-949 x555444433'
вот то, что я имею до сих пор.
public static string _FormatPhone(object phonevalue)
{
Int64 phoneDigits;
if (Int64.TryParse(phonevalue.ToString(), out phoneDigits))
{
string cleanPhoneDigits = phoneDigits.ToString();
int digitCount = cleanPhoneDigits.Length;
if (digitCount == 10)
return String.Format("{0:(###) ###-####}", phoneDigits);
else if (digitCount > 10)
return String.Format("{0:(###) ###-#### x#########}", phoneDigits);
else
return cleanPhoneDigits;
}
return "Format Err#";
}
Заранее спасибо.
Думаю, вам придется разбить строку phoneDigits на первые 10 цифр и остальные.
//[snip]
else if (phoneDigits.ToString().Length > 10)
{
return String.Format("{0:(###) ###-#### x}{1}", phoneDigits.Substring(0,10), phoneDigits.Substring(10) );
}
//[snip]
Я бы предложил рассматривать его как строку цифр, а не как число. Затем вы могли бы явно использовать Substring, чтобы разбить части.
с использованием регулярного выражения:
Regex usPhoneRegex = new Regex(@"(\d{3})(\d{3})(\d{4})(.*)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
string USPhoneFormatString = "$1-$2-$3 x$4";
return usPhoneRegex.Replace("312588230012999", USPhoneFormatString));
Все, что находится после основного номера телефона, будет возвращено как расширение
Поскольку вы использовали int64 в своем коде, мое регулярное выражение предполагает, что в номере телефона нет пробелов или знаков препинания.
- Изменить - Ахмад указал, что я не занимался случаем числа без добавочного номера. Итак, вот исправленная версия, в которой для выполнения этой работы используется MatchEvaluator. Это лучше, чем другие ответы? Я не знаю, но это другой подход, поэтому я подумал, что выброшу его там.
Regex usPhoneRegex = new Regex(@"(\d{3})(\d{3})(\d{4})(.*)", RegexOptions.IgnoreCase | RegexOptions.Compiled);
return usPhoneRegex.Replace("3125882300", new MatchEvaluator(MyClass.formatPhone))
public static string formatPhone(Match m) {
int groupIndex = 0;
string results = string.Empty;
foreach (Group g in m.Groups) {
groupIndex +=1;
switch (groupIndex) {
case 2 :
results = g.Value;
break;
case 3 :
case 4 :
results += "-" + g.Value;
break;
case 5 :
if (g.Value.Length != 0) {
results += " x " + g.Value;
}
break;
}
}
return results;
}
Вероятно, здесь следует использовать StringBuilder.
Проблема заключается в вашем else if
условии, где у вас есть заданное количество #
заполнителей для обработки расширения телефонного номера. Вместо этого мы можем определить формат динамически, чтобы учесть различную длину.
Почему вы передаете объект
? Вы повсюду используете ToString()
. Почему бы с самого начала не передать строку
? Если элемент, который вы передаете, не является строкой, то вызовите ToString
перед передачей, или сохраните результат ToString()
в переменной в методе, как показано ниже.
Вот обновленная версия вашего метода:
public static string _FormatPhone(object phonevalue)
{
string returnPhone = "Format Err#";
Int64 phoneDigits;
string phoneNumber = phonevalue.ToString();
if (Int64.TryParse(phoneNumber, out phoneDigits))
{
if (phoneNumber.Length == 10)
{
return phoneDigits.ToString("(###) ###-####");
}
else if (phoneNumber.Length > 10)
{
// determine the length of placeholders needed for the format
string format = "(###) ###-#### x"
+ new string('#', phoneNumber.Length - 10);
return phoneDigits.ToString(format);
}
else
{
return phoneNumber;
}
}
return returnPhone;
}
Для проверки:
string[] inputs = { "456", "4445552222", "444555222288", "44455522226789" };
foreach (string input in inputs)
{
Console.WriteLine("Format Result: " + _FormatPhone(input));
}
В этом случае нет необходимости в regex. Если вы действительно хотите его использовать, ваш метод замены должен определить длину, чтобы добавить расширение, когда это необходимо, как показано ниже:
string[] inputs = { "456", "4445552222", "444555222288", "44455522226789" };
string pattern = @"(\d{3})(\d{3})(\d{4})(\d*)";
foreach (string input in inputs)
{
string result = Regex.Replace(input, pattern, m =>
{
if (m.Value.Length >= 10)
{
return String.Format("({0}) {1}-{2}",
m.Groups[1].Value, m.Groups[2].Value, m.Groups[3].Value)
+ (m.Value.Length > 10 ? " x" + m.Groups[4].Value : "");
}
return m.Value;
});
Console.WriteLine("Regex result: " + result);
}
Попробуйте использовать регулярные выражения:
class Program
{
static void Main(string[] args)
{
var g = FormatUSPhone("444555222234");
}
public static string FormatUSPhone(string num)
{
string results = string.Empty;
if(num.Length == 10)
{
num = num.Replace("(", "").Replace(")", "").Replace("-", "");
const string formatPattern = @"(\d{3})(\d{3})(\d{4})";
results = Regex.Replace(num, formatPattern, "($1) $2-$3");
}else if (num.Length == 12)
{
num = num.Replace("(", "").Replace(")", "").Replace("-", "");
const string formatPattern = @"(\d{3})(\d{3})(\d{4})(\d{2})";
results = Regex.Replace(num, formatPattern, "($1) $2-$3 x$4");
}
return results;
}
Я отредактировал вышесказанное из примера, который я нашел здесь. Поиграйте с приведенным выше кодом, посмотрите, поможет ли он вам.