Я пытаюсь найти и заменить все числа в тексте. Я нашел несколько примеров регулярных выражений, которые почти решают проблему, но пока нет идеальных. У меня проблема в том, что числа в моем тексте могут иметь или не иметь десятичные дроби и запятые. Например:
«5000-фунтовая лиса перепрыгнула через забор размером 99 999,99998713 футов».
Регулярное выражение должно возвращать " 5000
" и " 99,999.99998713
". Примеры, которые я нашел, разбивают числа на запятую или ограничиваются двумя десятичными знаками. Я начинаю понимать регулярные выражения достаточно, чтобы понять, почему некоторые примеры ограничены двумя десятичными знаками, но я еще не научился преодолевать это, а также включать запятую, чтобы получить всю последовательность.
Вот моя последняя версия:
[0-9]+(\.[0-9][0-9]?)?
Что возвращает " 5000
", " 99,99
", " 9.99
" и " 998713
" для приведенного выше текста.
.,.,.
или9,9,9,9
или9,9.99.9
. Эти регулярные выражения не требуют, чтобы числа были в правильном формате, и в худшем случае они будут рассматривать знаки препинания как числа. Возможны некоторые дополнительные настройки (например, разрешить ли начальные и конечные нули), но некоторые из ответов, которые я вижу, совершенно неверны. Мне действительно не нравится голосование против, особенно при честных попытках, но я чувствую, что ответы здесь нужно очистить. Это частый вопрос, и его обязательно зададут снова.Ответы:
РЕДАКТИРОВАТЬ: Поскольку это набрало много просмотров, позвольте мне начать с того, что расскажу всем, что они искали в Google:
Теперь, когда это не в порядке, большая часть следующего предназначена для комментариев о том, насколько сложным может быть регулярное выражение, если вы попытаетесь с ним поумничать, и почему вам следует искать альтернативы. Читайте на свой страх и риск.
Это очень распространенная задача, но все ответы , которые я вижу здесь до сих пор принимают входные сигналы , которые не соответствуют вашему формат чисел, например
,111
,9,9,9
или даже.,,.
. Это достаточно просто исправить, даже если числа встроены в другой текст. ИМХО ничего , что не в состоянии тянуть 1,234.56 и 1234- и только те номера отъезда изabc22 1,234.56 9.9.9.9 def 1234
неправильного ответа.Прежде всего, если вам не нужно делать все это в одном регулярном выражении, не делайте этого. Одно регулярное выражение для двух разных числовых форматов трудно поддерживать, даже если они не встроены в другой текст. Что вам действительно нужно сделать, так это разделить все это на пробелы, а затем запустить два или три меньших регулярных выражения для результатов. Если это не вариант для вас, продолжайте читать.
Базовый шаблон
Учитывая приведенные вами примеры, вот простое регулярное выражение, которое допускает практически любые целые или десятичные числа в
0000
формате и блокирует все остальное:Вот тот, который требует
0,000
формата:Соедините их вместе, и запятые станут необязательными, если они согласованы:
Встроенные числа
Приведенные выше шаблоны требуют, чтобы весь ввод был числом. Вы ищете числа, встроенные в текст, поэтому вам нужно ослабить эту часть. С другой стороны, вы не хотите, чтобы он видел
catch22
и думал, что нашел число 22. Если вы используете что-то с поддержкой ретроспективного просмотра (например, .NET), это довольно просто: замените^
на(?<!\S)
и$
на,(?!\S)
и все хорошо. идти:Если вы работаете с JavaScript, Ruby или чем-то еще, все становится сложнее:
Вам придется использовать группы захвата; Я не могу придумать альтернативы без поддержки со стороны. Нужные вам числа будут в группе 1 (при условии, что все совпадение относится к группе 0).
Проверка и более сложные правила
Думаю, это отвечает на ваш вопрос, так что если это все, что вам нужно, прекратите читать сейчас. Если вы хотите стать более привлекательным, все очень быстро становится сложным. В зависимости от вашей ситуации вы можете заблокировать любое или все из следующего:
На всякий случай предположим, что вы хотите заблокировать первые 3, но разрешите последний. Что вы должны сделать? Я скажу вам, что вам следует делать: вы должны использовать разные регулярные выражения для каждого правила и постепенно сужать количество совпадений. Но ради сложности, вот как вы все это делаете в одном гигантском шаблоне:
И вот что это значит:
Протестировано здесь: http://rextester.com/YPG96786
Это позволит делать такие вещи, как:
Он заблокирует такие вещи, как:
Есть несколько способов сделать это регулярное выражение проще и короче, но помните, что изменение шаблона ослабит то, что он считает числом.
Поскольку многие механизмы регулярных выражений (например, JavaScript и Ruby) не поддерживают отрицательный просмотр назад, единственный способ сделать это правильно - использовать группы захвата:
Номера, которые вы ищете, будут в группе захвата 1.
Проверено здесь: http://rubular.com/r/3HCSkndzhT
Последнее замечание
Очевидно, это массивное, сложное, почти нечитаемое регулярное выражение. Мне понравилась эта задача, но вы должны подумать, действительно ли вы хотите использовать это в производственной среде. Вместо того, чтобы пытаться сделать все за один шаг, вы можете сделать это за два: регулярное выражение, чтобы поймать все, что может быть числом, и другое, чтобы отсеять то, что не является числом. Или вы можете выполнить некоторую базовую обработку, а затем использовать встроенные в ваш язык функции анализа чисел. Твой выбор.
источник
Несколько дней назад я работал над проблемой удаления конечных нулей из строки числа .
В продолжении этой проблемы я нахожу эту интересную, потому что она расширяет проблему до чисел, содержащих запятые.
Я взял шаблон регулярного выражения, который написал в предыдущей задаче, над которой работал, и улучшил его, чтобы он мог обрабатывать числа с запятыми как ответ на эту проблему.
Я был увлечен своим энтузиазмом и моей любовью к регулярным выражениям. Я не знаю, соответствует ли результат требованиям Майкла Прескотта. Мне было бы интересно узнать лишние или отсутствующие точки в моем регулярном выражении и исправить их, чтобы сделать их более подходящими для вас.
Теперь, после долгого сеанса работы с этим регулярным выражением, у меня возник какой-то груз в мозгу, поэтому я недостаточно свеж, чтобы давать много объяснений. Если вопросы неясны, и если кто-то может заинтересоваться достаточно, спросите меня.
Регулярное выражение построено для того, чтобы оно могло обнаруживать числа, выраженные в экспоненциальной нотации 2E10 или даже 5,22,454.12E-00.0478 , удаляя ненужные нули и в двух частях таких чисел. Если показатель степени равен нулю, число изменяется так, чтобы экспоненты больше не было.
Я ввел некоторую проверку в шаблон, чтобы некоторые частные случаи не совпадали, например, '12 ..57 ' не будет совпадать. Но в ', 111' строка '111' соответствует, потому что предыдущая запятая считается запятой не в числе, а в предложении.
Я думаю, что управление запятыми должно быть улучшено, потому что мне кажется, что в индийской нумерации между запятыми всего 2 цифры. Полагаю, исправить будет несложно.
Вот код, демонстрирующий, как работает мое регулярное выражение. Есть две функции, в зависимости от того, нужно ли преобразовывать числа «.1245» в «0,1245» или нет. Я не удивлюсь, если в некоторых случаях числовых строк останутся ошибки или нежелательные сопоставления или несоответствия; тогда я хотел бы знать эти случаи, чтобы понять и исправить недостаток.
Прошу прощения за этот код, написанный на Python, но регулярные выражения являются трансляционными, и я думаю, что каждый сможет понять шаблон reex.
результат
источник
Регулярное выражение ниже будет соответствовать обоим числам из вашего примера.
Он вернет 5000 и 99,999.99998713 - в соответствии с вашими требованиями.
источник
this,that
.\b\d[\d,.]+\b
9....9
или1,,,,X
(хотя X не будет включен в матч).\b\d[\d,.]*\b
достаточно близко, что если вы отредактируете свой ответ, я уберу -1. Это должно быть * вместо +;\b\d[\d,.]+\b
не допускает однозначных чисел.Освободившись от требований, вы ищете
Но обратите внимание, что это будет соответствовать, например, 11,11,1
источник
\d+([\d,]?\d)*(\.\d+)?
вместо\d+(,\d+)*(\.\d+)?
? Думаю, они дали бы эквивалентные совпадения, хотя группы захвата были бы разными.Это предполагает, что всегда есть по крайней мере одна цифра до или после любой запятой или десятичной дроби, а также предполагает, что существует не более одного десятичного числа и что все запятые предшествуют десятичному.
источник
999999,9,9,9,9
.(,\d+)
на(,\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
источник
Вот регулярное выражение:
который принимает числа:
123456789
,123.123
123 456 789
,123 456 789.100
,123,456
,3,232,300,000.00
Тесты: http://regexr.com/3h1a2
источник
Вот еще одна конструкция, которая начинается с простейшего числового формата, а затем, не перекрываясь, постепенно добавляет более сложные числовые форматы:
Java regep:
В качестве строки Java (обратите внимание на дополнительные \, необходимые для перехода к \ и., Поскольку \ и. Имеют особое значение в регулярном выражении, когда они сами по себе):
Пояснение:
Это регулярное выражение имеет вид A | B | C | D | E | F, где A, B, C, D, E, F сами по себе регулярные выражения, которые не перекрываются. Как правило, мне легче начать с простейших возможных совпадений A. Если A пропускает нужные совпадения, создайте B, который является незначительной модификацией A и включает немного больше того, что вы хотите. Затем, основываясь на B, создайте C, который улавливает больше, и т. Д. Я также считаю, что проще создавать регулярные выражения, которые не перекрываются; Легче понять регулярное выражение с 20 простыми неперекрывающимися регулярными выражениями, связанными с операциями OR, чем несколько регулярных выражений с более сложным сопоставлением. Но, каждому свое!
A - это (\ d) и соответствует ровно одному из 0,1,2,3,4,5,6,7,8,9, что не может быть проще!
B равен ([1-9] \ d +) и соответствует только числам с 2 или более цифрами, первая исключает 0. B соответствует точно одному из 10,11,12, ... B не перекрывает A, но является небольшой модификацией A.
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.
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.
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.
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.
Сообщите мне, если вам интересно, и я могу отредактировать выше, чтобы обработать конечные нули справа по желанию.
Вот что соответствует регулярному выражению, а что нет:
источник
\ b -------> граница слова
\ d + ------> один или цифра
, --------> содержащие запятые,
Например:
sddsgg 70,000 sdsfdsf fdgfdg70,00
sfsfsd 5,44,4343 5,7788,44 555
Он будет соответствовать:
70,
5,
44,
, 44
источник
Это будет соответствовать любому маленькому или большому числу, как показано ниже, с запятой или без нее
или
источник