как извлечь десятичное число из строки в c#
string sentence = "X10 cats, Y20 dogs, 40 fish and 1 programmer.";
string[] digits = Regex.Split (sentence, @"D+");
для этого кода я получаю значения в массиве цифр, как этот 10,20,40,1
string sentence = "X10.4 cats, Y20.5 dogs, 40 fish and 1 programmer.";
string[] digits = Regex.Split (sentence, @"D+");
для этого кода я получаю значения в массиве цифр, как этот 10,4,20,5,40,1
но мне нравится получать 10.4, 20.5, 40, 1 в десятичных числах, как я могу это сделать.
7 ответов
небольшое улучшение решения @Michael:
// NOTES: about the LINQ:
// .Where() == filters the IEnumerable (which the array is)
// (c=>...) is the lambda for dealing with each element of the array
// where c is an array element.
// .Trim() == trims all blank spaces at the start and end of the string
var doubleArray = Regex.Split(sentence, @"[^0-9\.]+")
.Where(c => c != "." && c.Trim() != "");
возвращает:
10.4
20.5
40
1
исходное решение возвращалось
[empty line here]
10.4
20.5
40
1
.
на decimal / float номер извлечения regex может отличаться в зависимости от того, используются ли и какие тысячи разделителей, какой символ обозначает десятичный разделитель, хочет ли он также соответствовать показателю, соответствует ли положительный или отрицательный знак, соответствует ли или нет числам, которые могут иметь ведущий 0
опущено, независимо от того, извлекает ли число, которое заканчивается десятичным разделителем.
A generic regex в соответствии с наиболее распространенным десятичные типы чисел находится в соответствие чисел с плавающей запятой с регулярным выражением:
[-+]?[0-9]*\.?[0-9]+(?:[eE][-+]?[0-9]+)?
я только изменил группу захвата на группу без захвата (добавлено ?:
после (
). соответствует
Если вам нужно сделать его еще более общим,если десятичный разделитель может быть точкой или запятой заменить \.
С классом персонажа (или скобочное выражение)[.,]
:
[-+]?[0-9]*[.,]?[0-9]+(?:[eE][-+]?[0-9]+)?
^^^^
Примечание выражения выше соответствуют целой и поплавки. чтобы соответствовать только float / десятичные числа убедитесь, что дробная часть шаблона обязательна, удалив второй ?
после \.
(демо):
[-+]?[0-9]*\.[0-9]+(?:[eE][-+]?[0-9]+)?
^
теперь 34
не соответствует: сочетается.
если вы не хотите соответствовать числам float без ведущие нули (например,.5
) сделать шаблон соответствия первой цифры обязательным (добавив +
кванторы, чтобы соответствовать 1 или более вхождений цифр):
[-+]?[0-9]+\.[0-9]+(?:[eE][-+]?[0-9]+)?
^
посмотреть демо. Теперь он соответствует гораздо меньшему количеству образцов:
теперь, что делать, если вы не хотите, чтобы соответствовать <digits>.<digits>
внутри <digits>.<digits>.<digits>.<digits>
? Как им соответствовать как целые слова? Использовать lookarounds:
[-+]?(?<!\d\.)\b[0-9]+\.[0-9]+(?:[eE][-+]?[0-9]+)?\b(?!\.\d)
и a демо здесь:
теперь, как насчет тех поплавков, которые имеют тысячи сепараторов, таких как 12 123 456.23
или 34,345,767.678
? Вы можете добавить (?:[,\s][0-9]+)*
после первого [0-9]+
чтобы соответствовать нулю или более последовательностям запятой или пробелов, за которыми следуют 1 + цифры:
[-+]?(?<![0-9]\.)\b[0-9]+(?:[,\s][0-9]+)*\.[0-9]+(?:[eE][-+]?[0-9]+)?\b(?!\.[0-9])
посмотреть regex demo:
замените запятую на \.
если вам нужно использовать запятая как десятичный разделитель и точка как разделитель тысяч.
теперь, как использовать эти шаблоны в C#?
var results = Regex.Matches(input, @"<PATTERN_HERE>")
.Cast<Match>()
.Select(m => m.Value)
.ToList();
Проверьте синтаксические лексемы для большинства языков программирования для регулярного выражения для десятичных знаков. Сопоставьте это регулярное выражение со строкой, найдя все совпадения.
если у вас есть Linq:
stringArray.Select(s=>decimal.Parse(s));
A foreach
также будет работать. Вам может потребоваться проверить, что each string
на самом деле число (.Parse
не бросает исключение en).
вам нужно будет учитывать десятичные знаки в вашем регулярном выражении. Попробуйте следующее:
\d+(\.\d+)?
Это будет соответствовать числам, а не всему, кроме чисел, но должно быть просто перебирать совпадения, чтобы построить Ваш массив.
что-то нужно иметь в виду, следует ли вам также искать отрицательные знаки, запятые и т. д.
кредит для следующего идет в @code4life. Все, что я добавил, Это цикл for для разбора целых / десятичных чисел перед возвратом.
public string[] ExtractNumbersFromString(string input)
{
input = input.Replace(",", string.Empty);
var numbers = Regex.Split(input, @"[^0-9\.]+").Where(c => !String.IsNullOrEmpty(c) && c != ".").ToArray();
for (int i = 0; i < numbers.Length; i++)
numbers[i] = decimal.Parse(numbers[i]).ToString();
return numbers;
}