Регулярное выражение для сопоставления чисел с запятыми и десятичными знаками в тексте или без них

97

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

«5000-фунтовая лиса перепрыгнула через забор размером 99 999,99998713 футов».

Регулярное выражение должно возвращать " 5000" и " 99,999.99998713". Примеры, которые я нашел, разбивают числа на запятую или ограничиваются двумя десятичными знаками. Я начинаю понимать регулярные выражения достаточно, чтобы понять, почему некоторые примеры ограничены двумя десятичными знаками, но я еще не научился преодолевать это, а также включать запятую, чтобы получить всю последовательность.

Вот моя последняя версия:

[0-9]+(\.[0-9][0-9]?)?

Что возвращает " 5000", " 99,99", " 9.99" и " 998713" для приведенного выше текста.

Пончик
источник
1
Какой язык программирования или разновидность регулярного выражения?
Мэтт Болл
7
Кажется, что почти каждый ответ здесь допускает такие вещи, как .,.,.или 9,9,9,9или 9,9.99.9. Эти регулярные выражения не требуют, чтобы числа были в правильном формате, и в худшем случае они будут рассматривать знаки препинания как числа. Возможны некоторые дополнительные настройки (например, разрешить ли начальные и конечные нули), но некоторые из ответов, которые я вижу, совершенно неверны. Мне действительно не нравится голосование против, особенно при честных попытках, но я чувствую, что ответы здесь нужно очистить. Это частый вопрос, и его обязательно зададут снова.
Джастин Морган
Если вы этого не знаете, взгляните на regexpal.com
entonio
Извините за задержку, Мэтт. Я использую Adobe ActionScript 3. Я думал, что поведение регулярных выражений такое же, как и в JavaScript, но я протестировал предложение Джастина на regexpal.com и сравнил его с результатами моего Flash-приложения и увидел два разных результата, оба неправильные.
Должно сработать на этот раз, основываясь на моих собственных тестах. Сообщите мне, если он все еще нуждается в доработке.
Джастин Морган

Ответы:

293

РЕДАКТИРОВАТЬ: Поскольку это набрало много просмотров, позвольте мне начать с того, что расскажу всем, что они искали в Google:

#ALL THESE REQUIRE THE WHOLE STRING TO BE A NUMBER
#For numbers embedded in sentences, see discussion below

#### NUMBERS AND DECIMALS ONLY ####
#No commas allowed
#Pass: (1000.0), (001), (.001)
#Fail: (1,000.0)
^\d*\.?\d+$

#No commas allowed
#Can't start with "."
#Pass: (0.01)
#Fail: (.01)
^(\d+\.)?\d+$

#### CURRENCY ####
#No commas allowed
#"$" optional
#Can't start with "."
#Either 0 or 2 decimal digits
#Pass: ($1000), (1.00), ($0.11)
#Fail: ($1.0), (1.), ($1.000), ($.11)
^\$?\d+(\.\d{2})?$

#### COMMA-GROUPED ####
#Commas required between powers of 1,000
#Can't start with "."
#Pass: (1,000,000), (0.001)
#Fail: (1000000), (1,00,00,00), (.001)
^\d{1,3}(,\d{3})*(\.\d+)?$

#Commas required
#Cannot be empty
#Pass: (1,000.100), (.001)
#Fail: (1000), ()
^(?=.)(\d{1,3}(,\d{3})*)?(\.\d+)?$

#Commas optional as long as they're consistent
#Can't start with "."
#Pass: (1,000,000), (1000000)
#Fail: (10000,000), (1,00,00)
^(\d+|\d{1,3}(,\d{3})*)(\.\d+)?$

#### LEADING AND TRAILING ZEROES ####
#No commas allowed
#Can't start with "."
#No leading zeroes in integer part
#Pass: (1.00), (0.00)
#Fail: (001)
^([1-9]\d*|0)(\.\d+)?$

#No commas allowed
#Can't start with "."
#No trailing zeroes in decimal part
#Pass: (1), (0.1)
#Fail: (1.00), (0.1000)
^\d+(\.\d*[1-9])?$

Теперь, когда это не в порядке, большая часть следующего предназначена для комментариев о том, насколько сложным может быть регулярное выражение, если вы попытаетесь с ним поумничать, и почему вам следует искать альтернативы. Читайте на свой страх и риск.


Это очень распространенная задача, но все ответы , которые я вижу здесь до сих пор принимают входные сигналы , которые не соответствуют вашему формат чисел, например ,111, 9,9,9или даже .,,.. Это достаточно просто исправить, даже если числа встроены в другой текст. ИМХО ничего , что не в состоянии тянуть 1,234.56 и 1234- и только те номера отъезда из abc22 1,234.56 9.9.9.9 def 1234неправильного ответа.

Прежде всего, если вам не нужно делать все это в одном регулярном выражении, не делайте этого. Одно регулярное выражение для двух разных числовых форматов трудно поддерживать, даже если они не встроены в другой текст. Что вам действительно нужно сделать, так это разделить все это на пробелы, а затем запустить два или три меньших регулярных выражения для результатов. Если это не вариант для вас, продолжайте читать.

Базовый шаблон

Учитывая приведенные вами примеры, вот простое регулярное выражение, которое допускает практически любые целые или десятичные числа в 0000формате и блокирует все остальное:

^\d*\.?\d+$

Вот тот, который требует 0,000формата:

^\d{1,3}(,\d{3})*(\.\d+)?$

Соедините их вместе, и запятые станут необязательными, если они согласованы:

^(\d*\.?\d+|\d{1,3}(,\d{3})*(\.\d+)?)$

Встроенные числа

Приведенные выше шаблоны требуют, чтобы весь ввод был числом. Вы ищете числа, встроенные в текст, поэтому вам нужно ослабить эту часть. С другой стороны, вы не хотите, чтобы он видел catch22и думал, что нашел число 22. Если вы используете что-то с поддержкой ретроспективного просмотра (например, .NET), это довольно просто: замените ^на (?<!\S)и $на, (?!\S)и все хорошо. идти:

(?<!\S)(\d*\.?\d+|\d{1,3}(,\d{3})*(\.\d+)?)(?!\S)

Если вы работаете с JavaScript, Ruby или чем-то еще, все становится сложнее:

(?:^|\s)(\d*\.?\d+|\d{1,3}(?:,\d{3})*(?:\.\d+)?)(?!\S)

Вам придется использовать группы захвата; Я не могу придумать альтернативы без поддержки со стороны. Нужные вам числа будут в группе 1 (при условии, что все совпадение относится к группе 0).

Проверка и более сложные правила

Думаю, это отвечает на ваш вопрос, так что если это все, что вам нужно, прекратите читать сейчас. Если вы хотите стать более привлекательным, все очень быстро становится сложным. В зависимости от вашей ситуации вы можете заблокировать любое или все из следующего:

  • Пустой ввод
  • Начальные нули (например, 000123)
  • Завершающие нули (например, 1,2340000)
  • Десятичные числа, начинающиеся с десятичной точки (например, 0,001 вместо 0,001)

На всякий случай предположим, что вы хотите заблокировать первые 3, но разрешите последний. Что вы должны сделать? Я скажу вам, что вам следует делать: вы должны использовать разные регулярные выражения для каждого правила и постепенно сужать количество совпадений. Но ради сложности, вот как вы все это делаете в одном гигантском шаблоне:

(?<!\S)(?=.)(0|([1-9](\d*|\d{0,2}(,\d{3})*)))?(\.\d*[1-9])?(?!\S)

И вот что это значит:

(?<!\S) to (?!\S) #The whole match must be surrounded by either whitespace or line boundaries. So if you see something bogus like :;:9.:, ignore the 9.
(?=.)             #The whole thing can't be blank.

(                    #Rules for the integer part:
  0                  #1. The integer part could just be 0...
  |                  #
  [1-9]              #   ...otherwise, it can't have leading zeroes.
  (                  #
    \d*              #2. It could use no commas at all...
    |                #
    \d{0,2}(,\d{3})* #   ...or it could be comma-separated groups of 3 digits each.
  )                  # 
)?                   #3. Or there could be no integer part at all.

(       #Rules for the decimal part:
  \.    #1. It must start with a decimal point...
  \d*   #2. ...followed by a string of numeric digits only.
  [1-9] #3. It can't be just the decimal point, and it can't end in 0.
)?      #4. The whole decimal part is also optional. Remember, we checked at the beginning to make sure the whole thing wasn't blank.

Протестировано здесь: http://rextester.com/YPG96786

Это позволит делать такие вещи, как:

100,000
999.999
90.0009
1,000,023.999
0.111
.111
0

Он заблокирует такие вещи, как:

1,1,1.111
000,001.111
999.
0.
111.110000
1.1.1.111
9.909,888

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

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

(:?^|\s)(?=.)((?:0|(?:[1-9](?:\d*|\d{0,2}(?:,\d{3})*)))?(?:\.\d*[1-9])?)(?!\S)

Номера, которые вы ищете, будут в группе захвата 1.

Проверено здесь: http://rubular.com/r/3HCSkndzhT

Последнее замечание

Очевидно, это массивное, сложное, почти нечитаемое регулярное выражение. Мне понравилась эта задача, но вы должны подумать, действительно ли вы хотите использовать это в производственной среде. Вместо того, чтобы пытаться сделать все за один шаг, вы можете сделать это за два: регулярное выражение, чтобы поймать все, что может быть числом, и другое, чтобы отсеять то, что не является числом. Или вы можете выполнить некоторую базовую обработку, а затем использовать встроенные в ваш язык функции анализа чисел. Твой выбор.

Джастин Морган
источник
1
Это очень хорошая попытка, но с ней может быть проблема - в зависимости от жадности движка данное число может частично совпадать с двумя конкурирующими форматами, если одно совпадение с правильным - то есть 5000 может дать 500 с лишним. 0 Это заставляет меня немного скептически относиться к попыткам охватить слишком много всего одним выражением, и поэтому я дал более простой ответ с оговоркой о возможных ложных срабатываниях. В конце концов, решение должно зависеть от строгости требований.
entonio
@entonio - Это справедливый вопрос. Это может работать с последним редактированием. Кстати, ваш отрицательный голос был не от меня, поскольку вы указали на возможное совпадение 1,11,11.
Джастин Морган
Я использую ActionScript, который, как мне кажется, ведет себя так же, как JavaScript. Используя первый рекомендованный вами шаблон, я получаю следующие результаты в своей тестовой строке (для проверки я просто возвращаю совпадения, заключенные в "<< [результат] >>"): << 5 >> 000 фунтов лиса перепрыгнул через << 9 >> 9 <<, 9 >> <<99>> <<. 9 >> <<99>> <<98>> <<71>> трехфутовый забор.
2
Что ж, один из ваших голосов за меня принадлежит мне :), так как я думаю, что ваш ответ настолько подробен, насколько это возможно, и вы вложили в него работу. Просто чтобы сделать это комментарий содержимого, примечание к OP,?: В начале групп есть, чтобы они не возвращались автономно в результате ('захвачены'), даже если они способствуют сопоставлению все выражение; каждое форматированное число во входных данных соответствует всему выражению.
entonio
@Michael и @entonio - см. Последнее изменение, которое, похоже, работает. Это одна из тех проблем с регулярными выражениями, которые сложнее, чем кажется.
Джастин Морган
10

Несколько дней назад я работал над проблемой удаления конечных нулей из строки числа .

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

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

Я был увлечен своим энтузиазмом и моей любовью к регулярным выражениям. Я не знаю, соответствует ли результат требованиям Майкла Прескотта. Мне было бы интересно узнать лишние или отсутствующие точки в моем регулярном выражении и исправить их, чтобы сделать их более подходящими для вас.

Теперь, после долгого сеанса работы с этим регулярным выражением, у меня возник какой-то груз в мозгу, поэтому я недостаточно свеж, чтобы давать много объяснений. Если вопросы неясны, и если кто-то может заинтересоваться достаточно, спросите меня.

Регулярное выражение построено для того, чтобы оно могло обнаруживать числа, выраженные в экспоненциальной нотации 2E10 или даже 5,22,454.12E-00.0478 , удаляя ненужные нули и в двух частях таких чисел. Если показатель степени равен нулю, число изменяется так, чтобы экспоненты больше не было.

Я ввел некоторую проверку в шаблон, чтобы некоторые частные случаи не совпадали, например, '12 ..57 ' не будет совпадать. Но в ', 111' строка '111' соответствует, потому что предыдущая запятая считается запятой не в числе, а в предложении.

Я думаю, что управление запятыми должно быть улучшено, потому что мне кажется, что в индийской нумерации между запятыми всего 2 цифры. Полагаю, исправить будет несложно.

Вот код, демонстрирующий, как работает мое регулярное выражение. Есть две функции, в зависимости от того, нужно ли преобразовывать числа «.1245» в «0,1245» или нет. Я не удивлюсь, если в некоторых случаях числовых строк останутся ошибки или нежелательные сопоставления или несоответствия; тогда я хотел бы знать эти случаи, чтобы понять и исправить недостаток.

Прошу прощения за этот код, написанный на Python, но регулярные выражения являются трансляционными, и я думаю, что каждый сможет понять шаблон reex.

import re

regx = re.compile('(?<![\d.])(?!\.\.)(?<![\d.][eE][+-])(?<![\d.][eE])(?<!\d[.,])'
                  '' #---------------------------------
                  '([+-]?)'
                  '(?![\d,]*?\.[\d,]*?\.[\d,]*?)'
                  '(?:0|,(?=0)|(?<!\d),)*'
                  '(?:'
                  '((?:\d(?!\.[1-9])|,(?=\d))+)[.,]?'
                  '|\.(0)'
                  '|((?<!\.)\.\d+?)'
                  '|([\d,]+\.\d+?))'
                  '0*'
                  '' #---------------------------------
                  '(?:'
                  '([eE][+-]?)(?:0|,(?=0))*'
                  '(?:'
                  '(?!0+(?=\D|\Z))((?:\d(?!\.[1-9])|,(?=\d))+)[.,]?'
                  '|((?<!\.)\.(?!0+(?=\D|\Z))\d+?)'
                  '|([\d,]+\.(?!0+(?=\D|\Z))\d+?))'
                  '0*'
                  ')?'
                  '' #---------------------------------
                  '(?![.,]?\d)')


def dzs_numbs(x,regx = regx): # ds = detect and zeros-shave
    if not regx.findall(x):
        yield ('No match,', 'No catched string,', 'No groups.')
    for mat in regx.finditer(x):
        yield (mat.group(), ''.join(mat.groups('')), mat.groups(''))

def dzs_numbs2(x,regx = regx): # ds = detect and zeros-shave
    if not regx.findall(x):
        yield ('No match,', 'No catched string,', 'No groups.')
    for mat in regx.finditer(x):
        yield (mat.group(),
               ''.join(('0' if n.startswith('.') else '')+n for n in mat.groups('')),
               mat.groups(''))

NS = ['  23456000and23456000. or23456000.000  00023456000 s000023456000.  000023456000.000 ',
      'arf 10000 sea10000.+10000.000  00010000-00010000. kant00010000.000 ',
      '  24:  24,  24.   24.000  24.000,   00024r 00024. blue 00024.000  ',
      '  8zoom8.  8.000  0008  0008. and0008.000  ',
      '  0   00000M0. = 000.  0.0  0.000    000.0   000.000   .000000   .0   ',
      '  .0000023456    .0000023456000   '
      '  .0005872    .0005872000   .00503   .00503000   ',
      '  .068    .0680000   .8   .8000  .123456123456    .123456123456000    ',
      '  .657   .657000   .45    .4500000   .7    .70000  0.0000023230000   000.0000023230000   ',
      '  0.0081000    0000.0081000  0.059000   0000.059000     ',
      '  0.78987400000 snow  00000.78987400000  0.4400000   00000.4400000   ',
      '  -0.5000  -0000.5000   0.90   000.90   0.7   000.7   ',
      '  2.6    00002.6   00002.60000  4.71   0004.71    0004.7100   ',
      '  23.49   00023.49   00023.490000  103.45   0000103.45   0000103.45000    ',
      '  10003.45067   000010003.45067   000010003.4506700 ',
      '  +15000.0012   +000015000.0012   +000015000.0012000    ',
      '  78000.89   000078000.89   000078000.89000    ',
      '  .0457e10   .0457000e10   00000.0457000e10  ',
      '   258e8   2580000e4   0000000002580000e4   ',
      '  0.782e10   0000.782e10   0000.7820000e10  ',
      '  1.23E2   0001.23E2  0001.2300000E2   ',
      '  432e-102  0000432e-102   004320000e-106   ',
      '  1.46e10and0001.46e10  0001.4600000e10   ',
      '  1.077e-300  0001.077e-300  0001.077000e-300   ',
      '  1.069e10   0001.069e10   0001.069000e10   ',
      '  105040.03e10  000105040.03e10  105040.0300e10    ',
      '  +286E000024.487900  -78.4500e.14500   .0140E789.  ',
      '  081,12.40E07,95.0120     0045,78,123.03500e-0.00  ',
      '  0096,78,473.0380e-0.    0008,78,373.066000E0.    0004512300.E0000  ',
      '  ..18000  25..00 36...77   2..8  ',
      '  3.8..9    .12500.     12.51.400  ',
      '  00099,111.8713000   -0012,45,83,987.26+0.000,099,88,44.or00,00,00.00must',
      '  00099,44,and   0000,099,88,44.bom',
      '00,000,00.587000  77,98,23,45.,  this,that ',
      '  ,111  145.20  +9,9,9  0012800  .,,.  1  100,000 ',
      '1,1,1.111  000,001.111   -999.  0.  111.110000  1.1.1.111  9.909,888']


for ch in NS:
    print 'string: '+repr(ch)
    for strmatch, modified, the_groups in dzs_numbs2(ch):
        print strmatch.rjust(20),'',modified,'',the_groups
    print

результат

string: '  23456000and23456000. or23456000.000  00023456000 s000023456000.  000023456000.000 '
            23456000  23456000  ('', '23456000', '', '', '', '', '', '', '')
           23456000.  23456000  ('', '23456000', '', '', '', '', '', '', '')
        23456000.000  23456000  ('', '23456000', '', '', '', '', '', '', '')
         00023456000  23456000  ('', '23456000', '', '', '', '', '', '', '')
       000023456000.  23456000  ('', '23456000', '', '', '', '', '', '', '')
    000023456000.000  23456000  ('', '23456000', '', '', '', '', '', '', '')

string: 'arf 10000 sea10000.+10000.000  00010000-00010000. kant00010000.000 '
               10000  10000  ('', '10000', '', '', '', '', '', '', '')
              10000.  10000  ('', '10000', '', '', '', '', '', '', '')
           10000.000  10000  ('', '10000', '', '', '', '', '', '', '')
            00010000  10000  ('', '10000', '', '', '', '', '', '', '')
           00010000.  10000  ('', '10000', '', '', '', '', '', '', '')
        00010000.000  10000  ('', '10000', '', '', '', '', '', '', '')

string: '  24:  24,  24.   24.000  24.000,   00024r 00024. blue 00024.000  '
                  24  24  ('', '24', '', '', '', '', '', '', '')
                 24,  24  ('', '24', '', '', '', '', '', '', '')
                 24.  24  ('', '24', '', '', '', '', '', '', '')
              24.000  24  ('', '24', '', '', '', '', '', '', '')
              24.000  24  ('', '24', '', '', '', '', '', '', '')
               00024  24  ('', '24', '', '', '', '', '', '', '')
              00024.  24  ('', '24', '', '', '', '', '', '', '')
           00024.000  24  ('', '24', '', '', '', '', '', '', '')

string: '  8zoom8.  8.000  0008  0008. and0008.000  '
                   8  8  ('', '8', '', '', '', '', '', '', '')
                  8.  8  ('', '8', '', '', '', '', '', '', '')
               8.000  8  ('', '8', '', '', '', '', '', '', '')
                0008  8  ('', '8', '', '', '', '', '', '', '')
               0008.  8  ('', '8', '', '', '', '', '', '', '')
            0008.000  8  ('', '8', '', '', '', '', '', '', '')

string: '  0   00000M0. = 000.  0.0  0.000    000.0   000.000   .000000   .0   '
                   0  0  ('', '0', '', '', '', '', '', '', '')
               00000  0  ('', '0', '', '', '', '', '', '', '')
                  0.  0  ('', '0', '', '', '', '', '', '', '')
                000.  0  ('', '0', '', '', '', '', '', '', '')
                 0.0  0  ('', '', '0', '', '', '', '', '', '')
               0.000  0  ('', '', '0', '', '', '', '', '', '')
               000.0  0  ('', '', '0', '', '', '', '', '', '')
             000.000  0  ('', '', '0', '', '', '', '', '', '')
             .000000  0  ('', '', '0', '', '', '', '', '', '')
                  .0  0  ('', '', '0', '', '', '', '', '', '')

string: '  .0000023456    .0000023456000     .0005872    .0005872000   .00503   .00503000   '
         .0000023456  0.0000023456  ('', '', '', '.0000023456', '', '', '', '', '')
      .0000023456000  0.0000023456  ('', '', '', '.0000023456', '', '', '', '', '')
            .0005872  0.0005872  ('', '', '', '.0005872', '', '', '', '', '')
         .0005872000  0.0005872  ('', '', '', '.0005872', '', '', '', '', '')
              .00503  0.00503  ('', '', '', '.00503', '', '', '', '', '')
           .00503000  0.00503  ('', '', '', '.00503', '', '', '', '', '')

string: '  .068    .0680000   .8   .8000  .123456123456    .123456123456000    '
                .068  0.068  ('', '', '', '.068', '', '', '', '', '')
            .0680000  0.068  ('', '', '', '.068', '', '', '', '', '')
                  .8  0.8  ('', '', '', '.8', '', '', '', '', '')
               .8000  0.8  ('', '', '', '.8', '', '', '', '', '')
       .123456123456  0.123456123456  ('', '', '', '.123456123456', '', '', '', '', '')
    .123456123456000  0.123456123456  ('', '', '', '.123456123456', '', '', '', '', '')

string: '  .657   .657000   .45    .4500000   .7    .70000  0.0000023230000   000.0000023230000   '
                .657  0.657  ('', '', '', '.657', '', '', '', '', '')
             .657000  0.657  ('', '', '', '.657', '', '', '', '', '')
                 .45  0.45  ('', '', '', '.45', '', '', '', '', '')
            .4500000  0.45  ('', '', '', '.45', '', '', '', '', '')
                  .7  0.7  ('', '', '', '.7', '', '', '', '', '')
              .70000  0.7  ('', '', '', '.7', '', '', '', '', '')
     0.0000023230000  0.000002323  ('', '', '', '.000002323', '', '', '', '', '')
   000.0000023230000  0.000002323  ('', '', '', '.000002323', '', '', '', '', '')

string: '  0.0081000    0000.0081000  0.059000   0000.059000     '
           0.0081000  0.0081  ('', '', '', '.0081', '', '', '', '', '')
        0000.0081000  0.0081  ('', '', '', '.0081', '', '', '', '', '')
            0.059000  0.059  ('', '', '', '.059', '', '', '', '', '')
         0000.059000  0.059  ('', '', '', '.059', '', '', '', '', '')

string: '  0.78987400000 snow  00000.78987400000  0.4400000   00000.4400000   '
       0.78987400000  0.789874  ('', '', '', '.789874', '', '', '', '', '')
   00000.78987400000  0.789874  ('', '', '', '.789874', '', '', '', '', '')
           0.4400000  0.44  ('', '', '', '.44', '', '', '', '', '')
       00000.4400000  0.44  ('', '', '', '.44', '', '', '', '', '')

string: '  -0.5000  -0000.5000   0.90   000.90   0.7   000.7   '
             -0.5000  -0.5  ('-', '', '', '.5', '', '', '', '', '')
          -0000.5000  -0.5  ('-', '', '', '.5', '', '', '', '', '')
                0.90  0.9  ('', '', '', '.9', '', '', '', '', '')
              000.90  0.9  ('', '', '', '.9', '', '', '', '', '')
                 0.7  0.7  ('', '', '', '.7', '', '', '', '', '')
               000.7  0.7  ('', '', '', '.7', '', '', '', '', '')

string: '  2.6    00002.6   00002.60000  4.71   0004.71    0004.7100   '
                 2.6  2.6  ('', '', '', '', '2.6', '', '', '', '')
             00002.6  2.6  ('', '', '', '', '2.6', '', '', '', '')
         00002.60000  2.6  ('', '', '', '', '2.6', '', '', '', '')
                4.71  4.71  ('', '', '', '', '4.71', '', '', '', '')
             0004.71  4.71  ('', '', '', '', '4.71', '', '', '', '')
           0004.7100  4.71  ('', '', '', '', '4.71', '', '', '', '')

string: '  23.49   00023.49   00023.490000  103.45   0000103.45   0000103.45000    '
               23.49  23.49  ('', '', '', '', '23.49', '', '', '', '')
            00023.49  23.49  ('', '', '', '', '23.49', '', '', '', '')
        00023.490000  23.49  ('', '', '', '', '23.49', '', '', '', '')
              103.45  103.45  ('', '', '', '', '103.45', '', '', '', '')
          0000103.45  103.45  ('', '', '', '', '103.45', '', '', '', '')
       0000103.45000  103.45  ('', '', '', '', '103.45', '', '', '', '')

string: '  10003.45067   000010003.45067   000010003.4506700 '
         10003.45067  10003.45067  ('', '', '', '', '10003.45067', '', '', '', '')
     000010003.45067  10003.45067  ('', '', '', '', '10003.45067', '', '', '', '')
   000010003.4506700  10003.45067  ('', '', '', '', '10003.45067', '', '', '', '')

string: '  +15000.0012   +000015000.0012   +000015000.0012000    '
         +15000.0012  +15000.0012  ('+', '', '', '', '15000.0012', '', '', '', '')
     +000015000.0012  +15000.0012  ('+', '', '', '', '15000.0012', '', '', '', '')
  +000015000.0012000  +15000.0012  ('+', '', '', '', '15000.0012', '', '', '', '')

string: '  78000.89   000078000.89   000078000.89000    '
            78000.89  78000.89  ('', '', '', '', '78000.89', '', '', '', '')
        000078000.89  78000.89  ('', '', '', '', '78000.89', '', '', '', '')
     000078000.89000  78000.89  ('', '', '', '', '78000.89', '', '', '', '')

string: '  .0457e10   .0457000e10   00000.0457000e10  '
            .0457e10  0.0457e10  ('', '', '', '.0457', '', 'e', '10', '', '')
         .0457000e10  0.0457e10  ('', '', '', '.0457', '', 'e', '10', '', '')
    00000.0457000e10  0.0457e10  ('', '', '', '.0457', '', 'e', '10', '', '')

string: '   258e8   2580000e4   0000000002580000e4   '
               258e8  258e8  ('', '258', '', '', '', 'e', '8', '', '')
           2580000e4  2580000e4  ('', '2580000', '', '', '', 'e', '4', '', '')
  0000000002580000e4  2580000e4  ('', '2580000', '', '', '', 'e', '4', '', '')

string: '  0.782e10   0000.782e10   0000.7820000e10  '
            0.782e10  0.782e10  ('', '', '', '.782', '', 'e', '10', '', '')
         0000.782e10  0.782e10  ('', '', '', '.782', '', 'e', '10', '', '')
     0000.7820000e10  0.782e10  ('', '', '', '.782', '', 'e', '10', '', '')

string: '  1.23E2   0001.23E2  0001.2300000E2   '
              1.23E2  1.23E2  ('', '', '', '', '1.23', 'E', '2', '', '')
           0001.23E2  1.23E2  ('', '', '', '', '1.23', 'E', '2', '', '')
      0001.2300000E2  1.23E2  ('', '', '', '', '1.23', 'E', '2', '', '')

string: '  432e-102  0000432e-102   004320000e-106   '
            432e-102  432e-102  ('', '432', '', '', '', 'e-', '102', '', '')
        0000432e-102  432e-102  ('', '432', '', '', '', 'e-', '102', '', '')
      004320000e-106  4320000e-106  ('', '4320000', '', '', '', 'e-', '106', '', '')

string: '  1.46e10and0001.46e10  0001.4600000e10   '
             1.46e10  1.46e10  ('', '', '', '', '1.46', 'e', '10', '', '')
          0001.46e10  1.46e10  ('', '', '', '', '1.46', 'e', '10', '', '')
     0001.4600000e10  1.46e10  ('', '', '', '', '1.46', 'e', '10', '', '')

string: '  1.077e-300  0001.077e-300  0001.077000e-300   '
          1.077e-300  1.077e-300  ('', '', '', '', '1.077', 'e-', '300', '', '')
       0001.077e-300  1.077e-300  ('', '', '', '', '1.077', 'e-', '300', '', '')
    0001.077000e-300  1.077e-300  ('', '', '', '', '1.077', 'e-', '300', '', '')

string: '  1.069e10   0001.069e10   0001.069000e10   '
            1.069e10  1.069e10  ('', '', '', '', '1.069', 'e', '10', '', '')
         0001.069e10  1.069e10  ('', '', '', '', '1.069', 'e', '10', '', '')
      0001.069000e10  1.069e10  ('', '', '', '', '1.069', 'e', '10', '', '')

string: '  105040.03e10  000105040.03e10  105040.0300e10    '
        105040.03e10  105040.03e10  ('', '', '', '', '105040.03', 'e', '10', '', '')
     000105040.03e10  105040.03e10  ('', '', '', '', '105040.03', 'e', '10', '', '')
      105040.0300e10  105040.03e10  ('', '', '', '', '105040.03', 'e', '10', '', '')

string: '  +286E000024.487900  -78.4500e.14500   .0140E789.  '
  +286E000024.487900  +286E24.4879  ('+', '286', '', '', '', 'E', '', '', '24.4879')
     -78.4500e.14500  -78.45e0.145  ('-', '', '', '', '78.45', 'e', '', '.145', '')
          .0140E789.  0.014E789  ('', '', '', '.014', '', 'E', '789', '', '')

string: '  081,12.40E07,95.0120     0045,78,123.03500e-0.00  '
081,12.40E07,95.0120  81,12.4E7,95.012  ('', '', '', '', '81,12.4', 'E', '', '', '7,95.012')
   0045,78,123.03500  45,78,123.035  ('', '', '', '', '45,78,123.035', '', '', '', '')

string: '  0096,78,473.0380e-0.    0008,78,373.066000E0.    0004512300.E0000  '
    0096,78,473.0380  96,78,473.038  ('', '', '', '', '96,78,473.038', '', '', '', '')
  0008,78,373.066000  8,78,373.066  ('', '', '', '', '8,78,373.066', '', '', '', '')
         0004512300.  4512300  ('', '4512300', '', '', '', '', '', '', '')

string: '  ..18000  25..00 36...77   2..8  '
           No match,  No catched string,  No groups.

string: '  3.8..9    .12500.     12.51.400  '
           No match,  No catched string,  No groups.

string: '  00099,111.8713000   -0012,45,83,987.26+0.000,099,88,44.or00,00,00.00must'
   00099,111.8713000  99,111.8713  ('', '', '', '', '99,111.8713', '', '', '', '')
  -0012,45,83,987.26  -12,45,83,987.26  ('-', '', '', '', '12,45,83,987.26', '', '', '', '')
         00,00,00.00  0  ('', '', '0', '', '', '', '', '', '')

string: '  00099,44,and   0000,099,88,44.bom'
           00099,44,  99,44  ('', '99,44', '', '', '', '', '', '', '')
     0000,099,88,44.  99,88,44  ('', '99,88,44', '', '', '', '', '', '', '')

string: '00,000,00.587000  77,98,23,45.,  this,that '
    00,000,00.587000  0.587  ('', '', '', '.587', '', '', '', '', '')
        77,98,23,45.  77,98,23,45  ('', '77,98,23,45', '', '', '', '', '', '', '')

string: '  ,111  145.20  +9,9,9  0012800  .,,.  1  100,000 '
                ,111  111  ('', '111', '', '', '', '', '', '', '')
              145.20  145.2  ('', '', '', '', '145.2', '', '', '', '')
              +9,9,9  +9,9,9  ('+', '9,9,9', '', '', '', '', '', '', '')
             0012800  12800  ('', '12800', '', '', '', '', '', '', '')
                   1  1  ('', '1', '', '', '', '', '', '', '')
             100,000  100,000  ('', '100,000', '', '', '', '', '', '', '')

string: '1,1,1.111  000,001.111   -999.  0.  111.110000  1.1.1.111  9.909,888'
           1,1,1.111  1,1,1.111  ('', '', '', '', '1,1,1.111', '', '', '', '')
         000,001.111  1.111  ('', '', '', '', '1.111', '', '', '', '')
               -999.  -999  ('-', '999', '', '', '', '', '', '', '')
                  0.  0  ('', '0', '', '', '', '', '', '', '')
          111.110000  111.11  ('', '', '', '', '111.11', '', '', '', '')
Eyquem
источник
8

Регулярное выражение ниже будет соответствовать обоим числам из вашего примера.

\b\d[\d,.]*\b

Он вернет 5000 и 99,999.99998713 - в соответствии с вашими требованиями.

Леон
источник
3
Это будет соответствовать запятой в this,that.
Джастин Морган
@ Джастин Морган - вы правы, я не проверял это условие. Вот обновленная версия, которая будет работать во всех случаях, за исключением номера, начинающегося с запятой или точки. \b\d[\d,.]+\b
Leons
Намного лучше, но он все равно позволит 9....9или 1,,,,X(хотя X не будет включен в матч).
Джастин Морган
1
Кстати, \b\d[\d,.]*\bдостаточно близко, что если вы отредактируете свой ответ, я уберу -1. Это должно быть * вместо +; \b\d[\d,.]+\bне допускает однозначных чисел.
Джастин Морган
@ Джастин Морган - спасибо за понимание. Этот вопрос был определенно более сложным, чем казалось. Я обновил свой ответ на основе ваших отзывов - это имеет смысл.
Leons
3

Освободившись от требований, вы ищете

\d+([\d,]?\d)*(\.\d+)?

Но обратите внимание, что это будет соответствовать, например, 11,11,1

Entonio
источник
Из любопытства, по какой причине вы пошли \d+([\d,]?\d)*(\.\d+)?вместо \d+(,\d+)*(\.\d+)?? Думаю, они дали бы эквивалентные совпадения, хотя группы захвата были бы разными.
Джастин Морган
Здравствуй. Нет особой причины, это было зависанием от начала с более сложного выражения, чтобы не соответствовать недопустимым форматам.
entonio
3
\d+(,\d+)*(\.\d+)?

Это предполагает, что всегда есть по крайней мере одна цифра до или после любой запятой или десятичной дроби, а также предполагает, что существует не более одного десятичного числа и что все запятые предшествуют десятичному.

Нил
источник
2
Это не ограничивает группы запятых трехзначным форматом. Он примет 999999,9,9,9,9.
Джастин Морган,
Хотя, наверное, стоит отметить, что это ближе к истине, чем большинство других. Ваш -1 не от меня.
Джастин Морган
Это RE, который я бы использовал, но с другим шагом проверки впоследствии (возможно, не с RE); попытка сделать все с помощью одного RE значительно усложняет жизнь.
Donal Fellows
@Justin Morgan Не было ясно, что запятая принимается только в трехзначных группах. Но это легко решить, если поменять (,\d+)на (,\d\d\d).
Нил
2

Это регулярное выражение:

(\d{1,3},\d{3}(,\d{3})*)(\.\d*)?|\d+\.?\d*

Соответствует каждому числу в строке:

1 1,0 0,1 1,001 1,000 1,000,000 1000,1 1,000,1 1,323,444,000 1,999 1,222,455,666,0 1,244

Эрик Д
источник
2

Вот регулярное выражение:

(?:\d+)((\d{1,3})*([\,\ ]\d{3})*)(\.\d+)?

который принимает числа:

  • без пробелов и / или десятичных знаков, например. 123456789,123.123
  • с запятыми или пробелами в качестве разделителя тысяч и / или десятичных знаков, например. 123 456 789, 123 456 789.100, 123,456,3,232,300,000.00

Тесты: http://regexr.com/3h1a2

Kacper Cz
источник
Это отлично работает на regexr.com, но в модуле python re не работает
Пардху
1

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

Java regep:

(\d)|([1-9]\d+)|(\.\d+)|(\d\.\d*)|([1-9]\d+\.\d*)|([1-9]\d{0,2}(,\d{3})+(\.\d*)?)

В качестве строки Java (обратите внимание на дополнительные \, необходимые для перехода к \ и., Поскольку \ и. Имеют особое значение в регулярном выражении, когда они сами по себе):

String myregexp="(\\d)|([1-9]\\d+)|(\\.\\d+)|(\\d\\.\\d*)|([1-9]\\d+\\.\\d*)|([1-9]\\d{0,2}(,\\d{3})+(\\.\\d*)?)";   

Пояснение:

  1. Это регулярное выражение имеет вид A | B | C | D | E | F, где A, B, C, D, E, F сами по себе регулярные выражения, которые не перекрываются. Как правило, мне легче начать с простейших возможных совпадений A. Если A пропускает нужные совпадения, создайте B, который является незначительной модификацией A и включает немного больше того, что вы хотите. Затем, основываясь на B, создайте C, который улавливает больше, и т. Д. Я также считаю, что проще создавать регулярные выражения, которые не перекрываются; Легче понять регулярное выражение с 20 простыми неперекрывающимися регулярными выражениями, связанными с операциями OR, чем несколько регулярных выражений с более сложным сопоставлением. Но, каждому свое!

  2. A - это (\ d) и соответствует ровно одному из 0,1,2,3,4,5,6,7,8,9, что не может быть проще!

  3. B равен ([1-9] \ d +) и соответствует только числам с 2 или более цифрами, первая исключает 0. B соответствует точно одному из 10,11,12, ... B не перекрывает A, но является небольшой модификацией A.

  4. C равен (. \ D +) и соответствует только десятичной дроби, за которой следует одна или несколько цифр. C соответствует точно одному из .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .00 .01 .02 .... .23000 ... C разрешает завершающий эрос справа, что я предпочитаю: если это данные измерений, количество конечных нулей указывает уровень точности. Если вам не нужны завершающие нули справа, измените (. \ D +) на (. \ D * [1-9]), но это также исключает .0, что, я думаю, должно быть разрешено. C также является небольшой модификацией A.

  5. D - это (\ d. \ D *), который представляет собой A плюс десятичные дроби с конечными нулями справа. D соответствует только одной цифре, за которой следует десятичная дробь, за которой следует ноль или более цифр. D соответствует 0. 0,0 0,1 0,2 .... 0,01000 ... 9. 9.0 9.1..0.0230000 .... 9.9999999999 ... Если вы хотите исключить "0" затем измените D на (\ d. \ d +). Если вы хотите исключить завершающие нули справа, измените D на (\ d. \ D * [1-9]), но это исключает 2.0, который, я думаю, должен быть включен. D не перекрывает A, B или C.

  6. E - это ([1-9] \ d +. \ D *), который представляет собой B плюс десятичные числа с конечными нулями справа. Если вы хотите исключить, например, «13», измените E на ([1-9] \ d +. \ D +). E не перекрывает A, B, C или D. E соответствует 10. 10.0 10.0100 .... 99.9999999999 ... Конечные нули можно обрабатывать, как в 4. и 5.

  7. F - это ([1-9] \ d {0,2} (, \ d {3}) + (. \ D *)?) И ​​сопоставляет только числа с запятыми и, возможно, десятичные дроби, разрешая завершающие нули справа. Первая группа ([1-9] \ d {0,2}) соответствует ненулевой цифре, за которой следует ноль, еще одна или две цифры. Вторая группа (, \ d {3}) + соответствует группе из 4 символов (запятая, за которой следуют ровно три цифры), и эта группа может соответствовать один или несколько раз (отсутствие совпадений означает отсутствие запятых!). Наконец, (. \ D *)? ничего не соответствует или совпадает. сам по себе или соответствует десятичному числу. за которым следует любое количество цифр, возможно, ни одного. Опять же, чтобы исключить такие вещи, как «1,111.», Измените (. \ D *) на (. \ D +). Конечные нули можно обрабатывать, как в 4. или 5. F не перекрывает A, B, C, D или E. Я не мог придумать более простого регулярного выражения для F.

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

Вот что соответствует регулярному выражению, а что нет:

0
1
02 <- invalid
20
22
003 <- invalid
030 <- invalid
300
033 <- invalid
303
330
333
0004 <- invalid
0040 <- invalid
0400 <- invalid
4000
0044 <- invalid
0404 <- invalid
0440 <- invalid
4004
4040
4400
0444 <- invalid
4044
4404
4440
4444
00005 <- invalid
00050 <- invalid
00500 <- invalid
05000 <- invalid
50000
00055 <- invalid
00505 <- invalid
00550 <- invalid
05050 <- invalid
05500 <- invalid
50500
55000
00555 <- invalid
05055 <- invalid
05505 <- invalid
05550 <- invalid
50550
55050
55500
. <- invalid
.. <- invalid
.0
0.
.1
1.
.00
0.0
00. <- invalid
.02
0.2
02. <- invalid
.20
2.0
20.
.22
2.2
22.
.000
0.00
00.0 <- invalid
000. <- invalid
.003
0.03
00.3 <- invalid
003. <- invalid
.030
0.30
03.0 <- invalid
030. <- invalid
.033
0.33
03.3 <- invalid
033. <- invalid
.303
3.03
30.3
303.
.333
3.33
33.3
333.
.0000
0.000
00.00 <- invalid
000.0 <- invalid
0000. <- invalid
.0004
0.0004
00.04 <- invalid
000.4 <- invalid
0004. <- invalid
.0044
0.044
00.44 <- invalid
004.4 <- invalid
0044. <- invalid
.0404
0.404
04.04 <- invalid
040.4 <- invalid
0404. <- invalid
.0444
0.444
04.44 <- invalid
044.4 <- invalid
0444. <- invalid
.4444
4.444
44.44
444.4
4444.
.00000
0.0000
00.000 <- invalid
000.00 <- invalid
0000.0 <- invalid
00000. <- invalid
.00005
0.0005
00.005 <- invalid
000.05 <- invalid
0000.5 <- invalid
00005. <- invalid
.00055
0.0055
00.055 <- invalid
000.55 <- invalid
0005.5 <- invalid
00055. <- invalid
.00505
0.0505
00.505 <- invalid
005.05 <- invalid
0050.5 <- invalid
00505. <- invalid
.00550
0.0550
00.550 <- invalid
005.50 <- invalid
0055.0 <- invalid
00550. <- invalid
.05050
0.5050
05.050 <- invalid
050.50 <- invalid
0505.0 <- invalid
05050. <- invalid
.05500
0.5500
05.500 <- invalid
055.00 <- invalid
0550.0 <- invalid
05500. <- invalid
.50500
5.0500
50.500
505.00
5050.0
50500.
.55000
5.5000
55.000
550.00
5500.0
55000.
.00555
0.0555
00.555 <- invalid
005.55 <- invalid
0055.5 <- invalid
00555. <- invalid
.05055
0.5055
05.055 <- invalid
050.55 <- invalid
0505.5 <- invalid
05055. <- invalid
.05505
0.5505
05.505 <- invalid
055.05 <- invalid
0550.5 <- invalid
05505. <- invalid
.05550
0.5550
05.550 <- invalid
055.50 <- invalid
0555.0 <- invalid
05550. <- invalid
.50550
5.0550
50.550
505.50
5055.0
50550.
.55050
5.5050
55.050
550.50
5505.0
55050.
.55500
5.5500
55.500
555.00
5550.0
55500.
.05555
0.5555
05.555 <- invalid
055.55 <- invalid
0555.5 <- invalid
05555. <- invalid
.50555
5.0555
50.555
505.55
5055.5
50555.
.55055
5.5055
55.055
550.55
5505.5
55055.
.55505
5.5505
55.505
555.05
5550.5
55505.
.55550
5.5550
55.550
555.50
5555.0
55550.
.55555
5.5555
55.555
555.55
5555.5
55555.
, <- invalid
,, <- invalid
1, <- invalid
,1 <- invalid
22, <- invalid
2,2 <- invalid
,22 <- invalid
2,2, <- invalid
2,2, <- invalid
,22, <- invalid
333, <- invalid
33,3 <- invalid
3,33 <- invalid
,333 <- invalid
3,33, <- invalid
3,3,3 <- invalid
3,,33 <- invalid
,,333 <- invalid
4444, <- invalid
444,4 <- invalid
44,44 <- invalid
4,444
,4444 <- invalid
55555, <- invalid
5555,5 <- invalid
555,55 <- invalid
55,555
5,5555 <- invalid
,55555 <- invalid
666666, <- invalid
66666,6 <- invalid
6666,66 <- invalid
666,666
66,6666 <- invalid
6,66666 <- invalid
66,66,66 <- invalid
6,66,666 <- invalid
,666,666 <- invalid
1,111.
1,111.11
1,111.110
01,111.110 <- invalid
0,111.100 <- invalid
11,11. <- invalid
1,111,.11 <- invalid
1111.1,10 <- invalid
01111.11,0 <- invalid
0111.100, <- invalid
1,111,111.
1,111,111.11
1,111,111.110
01,111,111.110 <- invalid
0,111,111.100 <- invalid
1,111,111.
1,1111,11.11 <- invalid
11,111,11.110 <- invalid
01,11,1111.110 <- invalid
0,111111.100 <- invalid
0002,22.2230 <- invalid
.,5.,., <- invalid
2.0,345,345 <- invalid
2.334.456 <- invalid
Дэвид Александр
источник
1
\b\d+,

\ b -------> граница слова

\ d + ------> один или цифра

, --------> содержащие запятые,

Например:

sddsgg 70,000 sdsfdsf fdgfdg70,00

sfsfsd 5,44,4343 5,7788,44 555

Он будет соответствовать:

70,

5,

44,

, 44

Ибз.Шайх
источник
0
(,*[\d]+,*[\d]*)+

Это будет соответствовать любому маленькому или большому числу, как показано ниже, с запятой или без нее

1
100
1,262
1,56,262
10,78,999
12,34,56,789

или

1
100
1262
156262
1078999
123456789
phpnerd
источник