Регулярное выражение для удаления разделителя тысяч из числовой строки? - PullRequest
6 голосов
/ 19 ноября 2011

У меня есть строки, которые содержат тысячи разделителей, однако ни одна функция строки в число не хочет использовать ее правильно (используя JavaScript). Я думаю о том, чтобы «подготовить» строку, удалив все тысячи разделителей, оставив все остальное нетронутым и позволив функциям Number / parseInt / parseFloat (я доволен их поведением в противном случае) решать остальное. Но кажется, что я понятия не имею, что RegExp может сделать это!

Лучшие идеи тоже приветствуются!


UPDATE:

Извините, ответы просветили меня, насколько это плохо сформулированный вопрос. Чего я хочу достичь, так это: 1) убрать тысячи разделителей, только если они есть, но 2) не сильно мешать исходной строке, поэтому я получу NaN в случае недопустимых чисел.

БОЛЬШЕ ОБНОВЛЕНИЙ:

JavaScript ограничен английской локалью для анализа, поэтому для простоты предположим, что разделитель тысяч - это ',' (естественно, он никогда не соответствует десятичному разделителю в любой локали, поэтому переход на любую другую локаль не должен создавать проблем)

Теперь о функциях разбора:

parseFloat('1023.95BARGAIN BYTES!')  // parseXXX functions just "gives up" on invalid chars and returns 1023.95
Number('1023.95BARGAIN BYTES!')      // while Number constructor behaves "strictly" and will return NaN

Иногда я использую rhw Свободный, иногда строгий. Я хочу выяснить лучший подход для подготовки строки для обеих функций.

О достоверности цифр:

'1,023.99' - это отлично сформированный английский номер, и удаление всех запятых приведет к правильному результату. '1,0,2,3.99' не работает, однако общее удаление запятой даст '1023.99', что вряд ли будет правильным результатом.

Ответы [ 7 ]

7 голосов
/ 19 ноября 2011

Welp, я рискну бросить мое предложение в банк:

Примечание: исправлено

stringWithNumbers = stringwithNumbers.replace(/(\d+),(?=\d{3}(\D|$))/g, "$1");

должно превратиться

1,234,567.12
1,023.99
1,0,2,3.99
the dang thing costs $1,205!!
95,5,0,432
12345,0000
1,2345

в:

1234567.12
1023.99
1,0,2,3.99
the dang thing costs $1205!!
95,5,0432
12345,0000
1,2345

Я надеюсь, что это полезно!

РЕДАКТИРОВАТЬ:

Существует дополнительное изменение, которое может быть необходимо, но этоне без побочных эффектов:

(\b\d{1,3}),(?=\d{3}(\D|$))

Изменяет квантификатор "один или несколько" (+) для первого набора цифр на квантификатор "один-три" ({1,3}) и добавляетутверждение "границы слова" перед ним.Это предотвратит замены типа 1234,123 ==> 1234123.Однако это также предотвратит замену, которая может быть желательной для (если ей предшествует буква или подчеркивание), такой как A123,789 или _1,555 (которая останется неизменной).

4 голосов
/ 19 ноября 2011

Простого num.replace(/,/g, '') должно быть достаточно, я думаю.

2 голосов
/ 19 ноября 2011

Зависит от того, какой у вас разделитель тысяч

myString = myString.replace(/[ ,]/g, "");

удалит пробелы и запятые.

1 голос
/ 12 сентября 2016

Вы можете использовать s.replaceAll("(\\W)(?=\\d{3})","");

Это регулярное выражение получает все буквенно-цифровые символы с 3 символами после него.

Строки типа 4.444.444.444,00 € будут 4444444444,00 €

1 голос
/ 11 июля 2016

Я использовал следующее в коммерческих условиях, и оно часто работало:

numberStr = numberStr.replace(/[. ,](\d\d\d\D|\d\d\d$)/g,'$1');

В приведенном выше примере тысячи можно пометить десятичной дробью, запятой,или пробел.

В некоторых случаях (например, цена 1000,5 евро) вышеуказанное не работает.Если вам нужно что-то более надежное, это должно работать 100% времени:

//convert a comma or space used as the cent placeholder to a decimal
$priceStr = $priceStr.replace(/[, ](\d\d$)/,'.$1');
$priceStr = $priceStr.replace(/[, ](\d$)/,'.$1');
//capture cents
var $hasCentsRegex = /[.]\d\d?$/;
if($hasCentsRegex.test($priceStr)) {
    var $matchArray = $priceStr.match(/(.*)([.]\d\d?$)/);
    var $priceBeforeCents = $matchArray[1];
    var $cents = $matchArray[2];    
} else{
    var $priceBeforeCents = $priceStr;
    var $cents = "";
}
//remove decimals, commas and whitespace from the pre-cent portion
$priceBeforeCents = $priceBeforeCents.replace(/[.\s,]/g,'');
//re-create the price by adding back the cents
$priceStr = $priceBeforeCents + $cents;
1 голос
/ 19 ноября 2011

Чтобы убедиться, что цифровая строка правильно сформирована, используйте:

/^(\d*|\d{1,3}(,\d{3})+)($|[^\d])/.test(numeral_string)

, который вернет true, если числовая строка либо (1) просто последовательность из нуля или более цифр, либо (2) последовательность цифр с запятой перед каждым набором из трех цифр, или (3) любой из вышеупомянутых сопровождается нецифровым символом и кто знает что еще. (Дело № 3 относится к числам с плавающей запятой, а также к вашим примерам «BARGAIN BYTES!».)

Как только вы подтвердите это, используйте:

numeral_string.replace(/,/g, '')

, который вернет копию строки цифр со всеми удаленными запятыми.

1 голос
/ 19 ноября 2011

Это должно работать для вас

var decimalCharacter = ".",
    regex = new RegExp("[\\d" + decimalCharacter + "]+", "g"),
    num = "10,0000,000,000.999";
+num.match(regex).join("");
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...