Регулярний вираз для видалення всіх (не числовий АБО період)


93

Мені потрібно, щоб текст типу "joe ($ 3,004,50)" був відфільтрований до 3004,50, але я страшний у регулярному виразі і не можу знайти підходяще рішення. Тож мають залишатися лише цифри та крапки - все інше відфільтровано. Я використовую C # та VS.net 2008 framework 3.5

Відповіді:


167

Це має зробити це:

string s = "joe ($3,004.50)";
s = Regex.Replace(s, "[^0-9.]", "");

1
Що про joe.smith ($3,004.50)? Просто видалення образливих класів персонажів може піти зовсім неправильно.
Метью Ганн,

2
Я роблю одну невеличку виправку: Regex.Replace(s, "[^$0-9.]", "");Ви хочете залишити знак долара.
bodacydo

35

Регулярний вираз:

[^0-9.]

Ви можете кешувати регулярний вираз:

Regex not_num_period = new Regex("[^0-9.]")

потім використовуйте:

string result = not_num_period.Replace("joe ($3,004.50)", "");

Однак слід пам’ятати, що деякі культури мають різні правила для написання грошових сум, наприклад: 3.004,50.


Занадто лінивий банкомат для перевірки, але чи не потрібно вам рятуватися від. ?
Ендрю Андерсон,

9
@Andrew: ні, всередині класу символів .не має особливого значення.
Барт Кірс,

2

Відповідно до прийнятої відповіді, MatthewGunn піднімає правильну думку, згідно з якою всі цифри, коми та крапки у всьому рядку будуть скорочені. Це дозволить уникнути того, що:

string s = "joe.smith ($3,004.50)";
Regex r = new Regex(@"(?:^|[^w.,])(\d[\d,.]+)(?=\W|$)/)");
Match m = r.match(s);
string v = null;
if (m.Success) {
  v = m.Groups[1].Value;
  v = Regex.Replace(v, ",", "");
}

Здається, над регулярним виразом є додаткові дужки. Використання (?:^|[^w.,])(\d[\d,.]+)(?=\W|$)також буде відповідати "h25" у рядку "joe.smith25 (3004,50 дол. США)"
Рівка

1

Підхід до видалення образливих персонажів є потенційно проблематичним. Що робити, якщо .десь у рядку є інший ? Він не буде видалений, хоча і повинен!

Видаляючи нецифрові чи крапки, рядок joe.smith ($3,004.50)перетворюється на нерозбірливий .3004.50.

Імхо, краще підібрати певний шаблон і витягти його за допомогою групи. Щось простим було б знайти всі суміжні коми, цифри та крапки з регулярним виразом:

[\d,\.]+

Зразок пробного запуску:

Pattern understood as:
[\d,\.]+
Enter string to check if matches pattern
>  a2.3 fjdfadfj34  34j3424  2,300 adsfa    
Group 0 match: "2.3"
Group 0 match: "34"
Group 0 match: "34"
Group 0 match: "3424"
Group 0 match: "2,300"

Потім для кожного збігу видаляйте всі коми і надсилайте їх до синтаксичного аналізатора. Щоб обробити випадок чогось подібного 12.323.344, ви можете зробити ще одну перевірку, щоб переконатися, що відповідний підрядок має не більше одного ..


Цей регулярний вираз відповідає усьому.
mindriot

Тепер він відповідає усім, крім "".
mindriot

1
Концепція, яку ви пропонуєте, вимагає складного регулярного виразу, який важко читати та налагоджувати. Можливо, краще розбити його на етапи за допомогою декількох регулярних виразів та умовних умов. Я міг би надати відповідь (хоча написано Ruby, оскільки я не знаю c #.
mindriot

@mindriot Очко взято. Я змінив його на щось більш прозоре.
Метью Ганн,

Під надсиланням до синтаксичного аналізатора ви маєте на увазі або Single.Parse()або Single.TryParse?
mindriot

1

Ви маєте справу з рядком - рядок є IEumerable<char>, тому ви можете використовувати LINQ:

var input = "joe ($3,004.50)";
var result = String.Join("", input.Where(c => Char.IsDigit(c) || c == '.'));

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