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


97

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

"Лиса на 5000 фунтів стрибнула через огорожу футом 99,999,99998713".

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

Ось моя остання версія:

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

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


1
Яка мова програмування чи регулярний вираз?
Matt Ball

7
Схоже , що майже кожен відповідь тут робить помилку, дозволяючи речі , як .,.,.або 9,9,9,9або 9,9.99.9. Ці регулярні вирази не вимагатимуть, щоб цифри були у відповідному форматі, і в гіршому випадку будуть трактувати пунктуацію як цифри. Можливі деякі необов’язкові налаштування (наприклад, чи дозволяти початкові та кінцеві нулі), але деякі відповіді, які я бачу, є абсолютно неправильними. Я дуже не люблю голосування, особливо на чесні спроби, але я відчуваю, що відповіді тут потребують очищення. Це поширене запитання, яке, безумовно, буде задано знову.
Джастін Морган,

Якщо ви цього не знаєте, загляньте на regexpal.com
entonio

Вибачте за затримку Метт. Я використовую ActionScript 3. Adobe. Я вважав, що поведінка регулярних виразів така ж, як і JavaScript, але я перевірив пропозицію Джастіна на сайті regexpal.com і порівняв її з результатами моєї програми Flash і побачив два різні результати, обидва неправильні.

Цього разу повинен працювати, виходячи з моїх власних тестів. Повідомте мене, чи все ще потребує доопрацювання.
Джастін Морган,

Відповіді:


289

РЕДАГУВАТИ: Оскільки це набрало багато переглядів, дозвольте мені розпочати з того, що дам усім те, заради чого вони шукали:

#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. Якщо ви використовуєте щось із підтримкою lookbehind (наприклад, .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)
  • Десяткові знаки, що починаються з десяткової коми (наприклад .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>> 3-футовий паркан.

2
Ну, один із ваших голосів за мене - від мене :), оскільки я думаю, що ваша відповідь настільки ретельна, наскільки це можливо, і ви вкладаєте в неї роботу. Просто, щоб зробити це коментарем до вмісту, приміткою до ОП,?: На початку груп є така, щоб вони не були повернуті автономно в результаті (`` захоплені ''), хоча вони і сприяють узгодженню весь вираз; кожне відформатоване число у вхідних даних відповідає цілому виразу.
entonio

@Michael and @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', '', '', '', '')

8

Звичайний вираз нижче буде відповідати обом цифрам з вашого прикладу.

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

Він поверне 5000 та 99,999,99998713 - що відповідає вашим вимогам.


3
Це буде відповідати комі в this,that.
Джастін Морган,

@Justin Morgan - ти прав, я не перевіряв на цей стан. Ось оновлена ​​версія, яка буде критичною для всіх випадків, за винятком числа, що починається з коми або періоду. \b\d[\d,.]+\b
Леонс

Набагато краще, але це все одно дозволить 9....9або 1,,,,X(хоча X не буде включено в матч).
Джастін Морган,

1
До речі, \b\d[\d,.]*\bдосить близько, що якщо ви відредагуєте свою відповідь, я видалю -1. Це має бути * замість +, хоча; \b\d[\d,.]+\bне дозволятиме однозначні номери.
Джастін Морган,

@Justin Morgan - дякую за розуміння. Це питання, безумовно, було більш складним, ніж здавалося. Я оновив свою відповідь на основі ваших відгуків - це має сенс.
Леонс

3

Беручи певну свободу з вимогами, ви шукаєте

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

Але зауважте, що це відповідатиме, наприклад, 11,11,1


З цікавості чи є якась причина, з якою ви пішли \d+([\d,]?\d)*(\.\d+)?замість цього \d+(,\d+)*(\.\d+)?? Я думаю, що вони давали б еквівалентні збіги, хоча групи захоплення були б різними.
Джастін Морган,

Привіт. Немає особливої ​​причини, це було затримка від початку з більш складного виразу, щоб не збігатися з недійсними форматами.
entonio

3
\d+(,\d+)*(\.\d+)?

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


2
Це не обмежує групи коми до 3-значного формату. Це прийме 999999,9,9,9,9.
Джастін Морган,

Хоча, мабуть, слід зазначити, що це ближче до правильності, ніж більшість інших. Твій -1 не від мене.
Джастін Морган,

Це RE, який я б використовував, хоча з іншим кроком перевірки після цього (можливо, не з RE); спроба зробити все одним РЕ ускладнює життя.
Donal Fellows

@Justin Morgan Не було зрозуміло, що кома приймається лише в 3-значних групах. Але це легко вирішується за рахунок зміни (,\d+)в (,\d\d\d)я думаю.
Ніл,

2

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

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

Відповідає кожному номеру в рядку:

1 1,0 0,1 1,0000 1 000 000 1000,1 1000,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


Це добре працює на regexr.com, але в модулі python re це не працює
Pardhu

1

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

Регепція Java:

(\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 пропускає збіги, які ви хочете, то створіть B, який є незначною модифікацією A і включає трохи більше того, що ви хочете. Потім, на основі B, створіть C, який вловлює більше тощо. Мені також легше створювати регулярні вирази, які не перекриваються; легше зрозуміти регулярний вираз із 20 простими неперекриваються регулярними виразами, пов’язаними з АБО, аніж декілька регулярних виразів із більш складним узгодженням. Але, кожен до свого!

  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, який, на мою думку, повинен бути дозволений. С - також невелика модифікація А.

  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 *)? нічого не відповідає, чи сірників. сам по собі або відповідає десятковій. за яким слід будь-яка кількість цифр, можливо жодна. Знову ж таки, щоб виключити такі речі, як "1111.", Змініть (. \ 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 70000 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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.