Викреслення нечислових символів у рядку


Відповіді:


235

Існує багато способів, але це має зробити (не знаю, як це працює з дійсно великими рядками):

private static string GetNumbers(string input)
{
    return new string(input.Where(c => char.IsDigit(c)).ToArray());
}

21
Напевно, ви повинні використовувати, IsDigitа не IsNumber: "Цей метод [ IsNumber] визначає, чи Charє будь-яка числова категорія Unicode. Крім включення цифр, цифри включають символи, дроби, підписки, надписи, римські цифри, чисельники валют та обведені цифри. Цей метод контрастує з IsDigitметодом, який визначає, чи a Char- це цифра-10-число ». msdn.microsoft.com/en-us/library/yk2b3t2y.aspx
— ЛукаХ

2
@TrevorBrooks Імовірно, ви можете просто розширити умови:input.Where(c => char.IsDigit(c) || char.IsWhiteSpace(c))
— Фредрік Мьорк

6
Можна додатково спростити це return new string(input.Where(char.IsDigit).ToArray());. Я просто робить його більш читабельним
— Zapnologica

2
Гарна відповідь. Можна просто розглянути можливість перейменування функції з "GetNumbers" на "GetDigits", а також ... щоб зробити свій намір зрозумілим.
— JTech

2
Це також чудовий метод розширення.
— Роберто Боніні

61

Відчуває себе гарним підходом до регулярного вираження.

var s = "40,595 p.a.";
var stripped = Regex.Replace(s, "[^0-9]", "");

"[^0-9]"можна замінити, @"\D"але мені подобається читабельність [^0-9].


1
Я погодився б, якщо ви добре з накладними, пов'язаними з регулярними виразами в. Net
— FrankO

4
З цікавості, яка ефективність роботи між цією відповіддю та відповіддю Фредріка Морка?
— Скуба Стів

Це, мабуть, повільніше, але єдиний спосіб знати - це вимірювання, оскільки це залежить від того, як .NET реалізує регулярні вирази, як компілюється Lambda Expression та інше.
— Jonas Elfström

1
Це більш гнучко, ніж використання IsDigit (), як ви можете додати "." символів у регулярному вираженні, якщо ви хочете дозволити числа з десятковими знаками.
— Річард Мур

10
Я здійснив просте порівняння Regex проти LINQ на рядку, побудованому з 100 000 GUID, з'єднаних разом (в результаті вийшло рядок 3 600 000 символів). Regex стабільно становив близько півсекунди, тоді як LINQ послідовно знаходився в 1/10 другого діапазону. В основному LINQ був в середньому в 5 і більше разів швидшим.
— Кріс Пратт

8

Кращим підходом стане метод розширення:

public static string GetNumbers(this string text)
    {
        text = text ?? string.Empty;
        return new string(text.Where(p => char.IsDigit(p)).ToArray());
    }

Я віддаю перевагу if (text == null) return string.Empty;понад text = text ?? string.Empty;. Таким чином ми не знижуємо продуктивність.
— Hooman

6

Використовуйте або регулярний вираз, який фіксує лише 0-9, а решту викидає. Регулярний вираз - це операція, яка коштуватиме вперше багато. Або зробити щось подібне:

var sb = new StringBuilder();
var goodChars = "0123456789".ToCharArray();
var input = "40,595";
foreach(var c in input)
{
  if(goodChars.IndexOf(c) >= 0)
    sb.Append(c);
}
var output = sb.ToString();

Щось подібне, я думаю, я ще не склав ..

LINQ - це, як сказав Фредрік, також варіант


4

Ще один варіант ...

private static string RemoveNonNumberDigitsAndCharacters(string text)
{
    var numericChars = "0123456789,.".ToCharArray();
    return new String(text.Where(c => numericChars.Any(n => n == c)).ToArray());
}

2
як щодо негативу? (-) не повинен мінус бути окрім цього?
— Seabizkit


0

Ну, ви знаєте, що таке цифри: 0123456789, правда? Перемістіть рядок за символом; якщо персонаж є цифрою, позначте його на кінці тимчасового рядка, інакше ігноруйте. Для рядків C # можуть бути доступні інші допоміжні методи, але це загальний підхід, який працює скрізь.


0

Ось код за допомогою регулярних виразів:

string str = "40,595 p.a.";

StringBuilder convert = new StringBuilder();

string pattern = @"\d+";
Regex regex = new Regex(pattern);

MatchCollection matches = regex.Matches(str);

foreach (Match match in matches)
{
convert.Append(match.Groups[0].ToString());
}

int value = Convert.ToInt32(convert.ToString()); 

Що мені потрібно зробити, щоб Regex Working отримував цю помилку Назва "Regex" не існує в поточному контексті
— StevieB

використання System.Text.RegularExpressions;
— dhirschl

0

Прийнята відповідь чудова, проте вона не враховує значення NULL, що робить її непридатною у більшості сценаріїв.

Це наштовхнуло мене на використання цих помічницьких методів. Перший відповідає на ОП, а другий може бути корисним для тих, хто хоче виконати навпаки:

    /// <summary>
    /// Strips out non-numeric characters in string, returning only digits
    /// ref.: /programming/3977497/stripping-out-non-numeric-characters-in-string
    /// </summary>
    /// <param name="input">the input string</param>
    /// <param name="throwExceptionIfNull">if set to TRUE it will throw an exception if the input string is null, otherwise it will return null as well.</param>
    /// <returns>the input string numeric part: for example, if input is "XYZ1234A5U6" it will return "123456"</returns>
    public static string GetNumbers(string input, bool throwExceptionIfNull = false)
    {
        return (input == null && !throwExceptionIfNull) 
            ? input 
            : new string(input.Where(c => char.IsDigit(c)).ToArray());
    }

    /// <summary>
    /// Strips out numeric and special characters in string, returning only letters
    /// </summary>
    /// <param name="input">the input string</param>
    /// <param name="throwExceptionIfNull">if set to TRUE it will throw an exception if the input string is null, otherwise it will return null as well.</param>
    /// <returns>the letters contained within the input string: for example, if input is "XYZ1234A5U6~()" it will return "XYZAU"</returns>
    public static string GetLetters(string input, bool throwExceptionIfNull = false)
    {
        return (input == null && !throwExceptionIfNull) 
            ? input 
            : new string(input.Where(c => char.IsLetter(c)).ToArray());
    }

    /// <summary>
    /// Strips out any non-numeric/non-digit character in string, returning only letters and numbers
    /// </summary>
    /// <param name="input">the input string</param>
    /// <param name="throwExceptionIfNull">if set to TRUE it will throw an exception if the input string is null, otherwise it will return null as well.</param>
    /// <returns>the letters contained within the input string: for example, if input is "XYZ1234A5U6~()" it will return "XYZ1234A5U6"</returns>
    public static string GetLettersAndNumbers(string input, bool throwExceptionIfNull = false)
    {
        return (input == null && !throwExceptionIfNull) 
            ? input 
            : new string(input.Where(c => char.IsLetterOrDigit(c)).ToArray());
    }

Для отримання додаткової інформації читайте це повідомлення в моєму блозі.


Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.