2013-11-22 2 views
5

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

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

Лучшее, что я получил до сих пор:

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

2 основные проблемы так далекий:

1) Он записывает числа с пробелами между ними «3001 1» вместо того, чтобы разбивать их на 2 соответствия «3001» «1» - я действительно не вижу, где я разрешил пространство в регулярном выражении.

2) У меня есть общая проблема с началом \ окончанием регулярного выражения.

Регулярное выражение должно соответствовать:

3,001 
1 
32,012,111.2131 

Но нет:

32,012,11.2131 
1132,012,111.2131 
32,0112,111.2131 
32131 

Кроме того, я хотел бы, чтобы соответствовать:

1.(without any number after it) 
1,(without any number after it) 
as 1 

(запятая или точка на конец номера следует упускать из виду).

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

+0

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

+0

Вы разрешили пробелы в регулярном выражении с периодом ('' '.'''), который соответствует любому символу. Выбери период ('' '\ .'''), чтобы просто соответствовать только периоду. – creemama

+0

Я не думаю, что вторая и третья проблемы - проблемы вообще. Из того, что я могу сказать, они не будут соответствовать тем, что они не должны. –

ответ

2

Это очень длинное и запутанное регулярное выражение, которое соответствует всем вашим требованиям. Он будет работать, если ваш механизм regex основан на PCRE (надеюсь, вы используете PHP, Delphi или R ..).

(?<=[^\d,.]|^)\d{1,3}(,(\d{3}))*((?=[,.](\s|$))|(\.\d+)?(?=[^\d,.]|$)) 

DEMO on RegExr

Вещи, которые делают его так долго:

  1. Matching несколько номеров на одной и той же линии, отделенной только один символ (пробел) в то время не допуская частичных вышлет нуждается в предпросмотр и взгляд.
  2. Соответствующие номера, оканчивающиеся на ., и , без учета . или , в матче требует другого взгляда.

(?=[,.](\s|$))Объяснение

При написании этого объяснения я понял, \s должен быть (\s|$), чтобы соответствовать 1, в самом конце строки.

Эта часть регулярного выражения для сопоставления 1 в 1, или 1,000 в 1,000. так скажем, наш номер 1,000.. на конце).

До этого момента регулярное выражение имеет согласованный 1,000, то она не может найти другого , повторить группу тысяч, так что движется по нашим (?=[,.](\s|$))

(?=....) означает Сво опережения, что означает, откуда мы имеем сопоставляемый, посмотрите, что произойдет, но не добавьте его в игру.

Таким образом, он проверяет наличие , или ., и если есть, он проверяет, что за ним сразу следует пробел или конец ввода. В этом случае это так, поэтому он оставил бы матч как 1,000

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

+0

Пока это отлично работает. Я проверю его немного больше. Большое спасибо! Можете ли вы, пожалуйста, объяснить: (? = [,.] \ S)? – LiranBo

+0

Хорошо, я добавлю это объяснение к ответу. – OGHaza

+0

Ответ обновлен - я должен был внести небольшое изменение в регулярное выражение, чтобы разрешить кромку. – OGHaza

1

Это работает для всех тех, которые вы перечислили

^[0-9]{1,3}(,[0-9]{3})*(([\\.,]{1}[0-9]*)|())$ 
+0

с тегами^$ ничего не возвращает. для приведенных выше примеров без него возвращает более нескольких примеров, которые не должны совпадать. – LiranBo

0

. означает «любой символ». Чтобы использовать литерал ., берите его вот так: \..

Насколько я знаю, это единственное, чего не хватает.

+0

Он хочет сопоставить несколько номеров в одной строке, поэтому с его текущим регулярным выражением он получает всевозможные нежелательные совпадения: [DEMO] (http://regexr.com?37asm) – OGHaza

+0

Какие нежелательные совпадения есть? В нижних строках есть частичные совпадения, но это допустимые числа. –

+0

Весьма маловероятно, что OP будет принимать частичные совпадения для входов, которые он указал как несоответствующие. Точно так же, как я спрашиваю вас о положительных числах в списке «1 -2 -3», и вы возвращаете «1», «2» и «3». Конечно, это положительные числа, которые встречаются в списке, но они были выведены из любого полезного контекста. – OGHaza

Смежные вопросы