Регулярное выражение большого объема для количества и цен в финансах

Я занимаюсь интеллектуальным анализом данных по огромному количеству финансовых данных, и мне нужно найти два регулярных выражения Python, которые соответствуют:

Цены, такие как:

16 666 666.67
16 666 666,67
666 666.67
5 567.1
5 677,1
0.0
0,101
5,4
5.40
54.0
5.675674754747457
5980990.009345
16,000.45
234,234,657.108

В цене всегда есть запятая или точка. Но перед запятой могут быть пробелы (пробелы должны быть согласованными, а не, например, 56 34.345)

Объем (количество), например:

9898
5
450934
5,000
1,000
1,000,000
5,998
11
0
5 000
1 000 000
1 980 000 000
599
233 590
23 613
181 876 980

Количество никогда не разделяется точками. Он не может иметь десятичных знаков в принципе.

Вот тот, который я пробовал для цен: (^[0-9]{0,}$)|(\d{1,}(?:[.,]\d{3})*(?:[.,]\d*)) Но я не могу обрабатывать пробелы.

А для объема мне очень сложно, так как везде тоже есть пробелы!

Большое спасибо.


person zakk8889    schedule 15.03.2019    source источник
comment
Каков ваш желаемый результат?   -  person FailSafe    schedule 15.03.2019
comment
Есть ли какой-то контекст вокруг этих чисел в строке, из которой вы пытаетесь сопоставить выражение, или вы получаете числа, как в ваших примерах? Если вокруг есть еще что-то, то было бы неплохо узнать об этом, чтобы помочь.   -  person TheKvist    schedule 15.03.2019
comment
@FailSafe Логическое значение в порядке, весь захваченный объем или количество лучше, как вы можете!   -  person zakk8889    schedule 15.03.2019
comment
@TheKvist Там могут быть (или что-то приклеено, да   -  person zakk8889    schedule 15.03.2019
comment
В ценах некоторые из запятых являются десятичными разделителями, а некоторые из них - разделителями цифр?   -  person CoffeeTableEspresso    schedule 15.03.2019
comment
Например, 0,1 совпадает с 0.1, но 1,000.0 отличается от 1,000?   -  person CoffeeTableEspresso    schedule 15.03.2019
comment
@CoffeeTableEspresso Без десятичного разделителя в виде запятой   -  person zakk8889    schedule 15.03.2019
comment
так что 0,101 совпадает с 101?   -  person CoffeeTableEspresso    schedule 15.03.2019
comment
@CoffeeTableExpresso 1,000.0и 1,000 идентичны   -  person zakk8889    schedule 15.03.2019
comment
Итак, позвольте мне посмотреть, если я понимаю. Вы хотите сопоставить такие вещи, как 666 666.67 и 5 567.1, но НЕ хотите, чтобы они соответствовали 56 34.345. Какую именно разницу вы хотите исключить в этих примерах?   -  person FailSafe    schedule 15.03.2019
comment
@CoffeTableEspresso 0,101 не должно быть возможным для количества. Я обновлю свой пост, количество всегда должно быть положительным и естественным   -  person zakk8889    schedule 15.03.2019
comment
@FailSafe 56 34.345 неправильно, правильно 5 634.345   -  person zakk8889    schedule 15.03.2019
comment
Где могут стоять запятые в ценах? Я думал, что изначально у вас было такое же ограничение на них, как и на пробелы, но у вас есть такие примеры, как 5,4.   -  person CoffeeTableEspresso    schedule 15.03.2019
comment
@FailSafe Извините, я не очень понимаю. В основном это цена, она может иметь десятичные дроби и форматы разные (европейские, американские), поэтому иногда тысячи разделены запятой, иногда разделены пробелом, если тысячи разделены точками, то запятой быть не должно (иначе не имеет смысла)   -  person zakk8889    schedule 15.03.2019
comment
@CoffeeTableEspresso 5,4 в порядке, 5.4 в порядке, 5,4.5 не в порядке, 5,400.5 в порядке   -  person zakk8889    schedule 15.03.2019
comment
под dot separated вы имеете в виду has a decimal place?   -  person CoffeeTableEspresso    schedule 15.03.2019
comment
Является ли 5,4 таким же, как 5.4 (только пишется по-другому)?   -  person CoffeeTableEspresso    schedule 15.03.2019
comment
@CoffeeTableEspresso Да, именно!   -  person zakk8889    schedule 15.03.2019
comment
@zakk8889 zakk8889, надеюсь, мой ответ поможет, дайте мне знать, если я что-то пропустил.   -  person CoffeeTableEspresso    schedule 15.03.2019


Ответы (1)


В этом случае я бы рекомендовал немного больше, чем просто регулярное выражение.

First, normalizing each line is good, since there's lots of acceptable formats. We'll normalize so that . is always the decimal separator and is always the thousand separator:

if '.' not in line:
    # `,` is our separator, so replace with `.`
    line = line.replace(',', '.')
else:
    # `.` is our separator, so replace `,` with ` ` (does nothing if already space separated).
    line = line.replace(',', ' ')

Now, we can apply the regex to line:

^\d{1,3}(\s\d{3})*\.\d+$ будет соответствовать чему-либо, разделенному тысячами. ^\d+\.\d+$ будет соответствовать чему угодно без разделения тысяч.

Обратите внимание: поскольку мы сделали небольшую предварительную обработку строк, наше регулярное выражение стало намного проще. Я оставлю количество один (должно быть проще) и отобрать для вас соответствующие части.

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

person CoffeeTableEspresso    schedule 15.03.2019
comment
Я воспользуюсь предложенным вами методом и попытаюсь вернуться с хорошей функцией. Спасибо - person zakk8889; 15.03.2019
comment
конечно, дайте мне знать, если это сработает (и если да, пожалуйста, примите этот ответ). - person CoffeeTableEspresso; 15.03.2019
comment
конечно, дайте мне немного времени, чтобы попробовать это! - person zakk8889; 15.03.2019