Если ваша цель состоит в том, чтобы определить, имеет ли строка правильную форму, и не обязательно использовать регулярное выражение, применяемое ко всей строке, чтобы сделать это определение, вы можете выполнить два шага, используя следующие регулярные выражения:
r1 = /(?<!,), ?/
r2 = /^\d+(?:\.\d{,2})?$/
Шаги:
- используйте
r1
, чтобы разбить строку на одну или несколько подстрок - определить, соответствуют ли все подстроки
r2
r1
читает, "соответствует запятой, за которой следует не более одного пробела, и перед ней не стоит запятая.
r2
читает," соответствует одной или нескольким цифрам в начале строки, необязательно, за которым следует десятичная точка, затем 0, 1 или 2 цифры, за которыми следует конец строки ".
В Ruby, например, получается следующее:
arr =<<~END.split("\n")
1.23
1
1,
1.2,4
1.23, 4
1.23, 4,
1, 2.34
1, 2.34
1,,
1.234
END
#=> ["1.23", "1", "1,", "1.2,4", "1.23, 4", "1.23, 4,", "1, 2.34",
# "1, 2.34", "1,,", "1.234"]
arr.each do |s|
a = s.split r1
result = a.all? { |t| t.match? r2 } ? "(Match)" : "(No match)"
puts "%-9s: %-14s %s" % [s, a.inspect, result]
end
string array match?
---------------------------------
1.23 : ["1.23"] (Match)
1 : ["1"] (Match)
1, : ["1"] (Match)
1.2,4 : ["1.2", "4"] (Match)
1.23, 4 : ["1.23", "4"] (Match)
1.23, 4, : ["1.23", "4"] (Match)
1, 2.34 : ["1", "2.34"] (Match)
1, 2.34 : ["1", " 2.34"] (No match)
1,, : ["1", ","] (No match)
1.234 : ["1.234"] (No match)
Важным преимуществом этого подхода является то, что тестирование намного проще, чем тестирование одного регулярного выражения на основе вся строка, как r1
и r2
может пройти тестирование отдельно. Этот подход также может быть легче адаптироваться к меняющимся требованиям в будущем.