У меня есть строка при вводе телефонного номера - есть маска, поэтому она всегда выглядит как "(123) 456-7890" - я хотел бы вынуть форматирование перед его сохранением в БД.
Как я могу это сделать?
Одна из возможностей использования linq:
string justDigits = new string(s.Where(c => char.IsDigit(c)).ToArray());
Добавление более чистой / более короткой версии благодаря craigmoliver
string justDigits = new string(s.Where(char.IsDigit).ToArray())
Вы можете заставить его работать для этого числа, добавив простую замену регулярного выражения, но я бы обратил внимание на более высокие начальные цифры. Например, (876) 543-2019
переполнит целочисленную переменную.
Вы можете использовать регулярное выражение или перебирать каждый символ в цикле и использовать функцию char.IsNumber .
string digits = Regex.Replace(formatted, @"\D", String.Empty, RegexOptions.Compiled);
Лучше использовать регулярные выражения . По определению int - это просто число, но вы хотите, чтобы символы форматирования сделали его телефонным номером, который является строкой.
Существует множество сообщений о проверке номера телефона, см. Комплексное регулярное выражение для проверки номера телефона для начала.
Альтернатива с использованием Linq:
string phoneNumber = "(403) 259-7898";
var phoneStr = new string(phoneNumber.Where(i=> i >= 48 && i <= 57).ToArray());
Вы можете использовать регулярное выражение для удаления всех нецифровых символов:
string phoneNumber = "(123) 456-7890";
phoneNumber = Regex.Replace(phoneNumber, @"[^\d]", "");
Далее - в зависимости от ваших требований - вы можете хранить число либо как строку, либо как целое число. Для преобразования числа в целочисленный тип у вас будут следующие возможности:
// throws if phoneNumber is null or cannot be parsed
long number = Int64.Parse(phoneNumber, NumberStyles.Integer, CultureInfo.InvariantCulture);
// same as Int64.Parse, but returns 0 if phoneNumber is null
number = Convert.ToInt64(phoneNumber);
// does not throw, but returns true on success
if (Int64.TryParse(phoneNumber, NumberStyles.Integer,
CultureInfo.InvariantCulture, out number))
{
// parse was successful
}
public static string DigitsOnly(this string phoneNumber)
{
return new string(
new[]
{
// phoneNumber[0], (
phoneNumber[1], // 6
phoneNumber[2], // 1
phoneNumber[3], // 7
// phoneNumber[4], )
// phoneNumber[5],
phoneNumber[6], // 8
phoneNumber[7], // 6
phoneNumber[8], // 7
// phoneNumber[9], -
phoneNumber[10], // 5
phoneNumber[11], // 3
phoneNumber[12], // 0
phoneNumber[13] // 9
});
}
Попробуйте следующее:
string s = "(123) 456-7890";
UInt64 i = UInt64.Parse(
s.Replace("(","")
.Replace(")","")
.Replace(" ","")
.Replace("-",""));
Вы должны быть в безопасности, так как ввод замаскирован.
Как уже упоминалось во многих ответах, вам нужно сначала удалить нецифровые символы, прежде чем пытаться проанализировать число. Вы можете сделать это с помощью регулярного выражения.
Regex.Replace("(123) 456-7890", @"\D", String.Empty) // "1234567890"
Однако обратите внимание, что наибольшее положительное значение, которое может содержать int, равно 2 147 483 647, поэтому любое число с кодом города больше 214 вызовет переполнение. В этой ситуации лучше использовать долго.
Начальные нули не будут проблемой для номеров в Северной Америке, поскольку коды городов не могут начинаться с нуля или единицы.
По сути, это частный случай C #: Удаление общих недопустимых символов из строки: улучшите этот алгоритм . Где ваш формат, вкл. Пробелы считаются "плохими символами"
Поскольку цикл for никто не выполнял.
long GetPhoneNumber(string PhoneNumberText)
{
// Returns 0 on error
StringBuilder TempPhoneNumber = new StringBuilder(PhoneNumberText.Length);
for (int i=0;i<PhoneNumberText.Length;i++)
{
if (!char.IsDigit(PhoneNumberText[i]))
continue;
TempPhoneNumber.Append(PhoneNumberText[i]);
}
PhoneNumberText = TempPhoneNumber.ToString();
if (PhoneNumberText.Length == 0)
return 0;// No point trying to parse nothing
long PhoneNumber = 0;
if(!long.TryParse(PhoneNumberText,out PhoneNumber))
return 0; // Failed to parse string
return PhoneNumber;
}
используется следующим образом:
long phoneNumber = GetPhoneNumber("(123) 456-7890");
Update
Как прокомментировал pr, во многих странах в начале числа есть нули, если вам нужно это поддержать, тогда вы должны вернуть строку не длинного размера. Чтобы изменить мой код для этого, сделайте следующее:
1) Измените тип возвращаемого значения функции с длинного на строковый.
2) Сделайте так, чтобы функция возвращала ноль вместо 0 при ошибке
.
3) При успешном синтаксическом анализе вернуть PhoneNumberText
Помимо всех остальных правильных ответов, хранение телефонных номеров в виде целых чисел или удаление форматирования может быть плохой идеей.
Вот несколько соображений:
(555) 555-5555 ext#343
Клавиша #
на самом деле находится в номеронабирателе/телефоне, но не может быть закодирована в целое число. Пользователям также может потребоваться ключ *
. P
), что может быть необходимо для расширений или систем меню, или набора номера в определенных телефонных системах (например, за рубежом). Они также не могут быть закодированы как целые числа. [EDIT]
Возможно, хорошей идеей будет хранить в базе данных как целочисленную, так и строковую версию. Кроме того, при хранении строк можно сократить всю пунктуацию до пробельных символов, используя один из методов, описанных выше. Регулярное выражение для этого может быть таким:
// (222) 222-2222 ext# 333 -> 222 222 2222 # 333
phoneString = Regex.Replace(phoneString, @"[^\d#*P]", " ");
// (222) 222-2222 ext# 333 -> 2222222222333 (information lost)
phoneNumber = Regex.Replace(phoneString, @"[^\d]", "");
// you could try to avoid losing "ext" strings as in (222) 222-2222 ext.333 thus:
phoneString = Regex.Replace(phoneString, @"ex\w+", "#");
phoneString = Regex.Replace(phoneString, @"[^\d#*P]", " ");