Try this expression: (?>-?\d+(?:[\./]\d+)?)
, keep in mind that in Java strings you need to escape the backslashes, i.e. you'd get "(?>-?\\d+(?:[\\./]\\d+)?)"
Here's a breakdown of the expression:
The encloseing (?>...)
is an atomic group to prevent catastrophic backtracking. For simple or short strings it would work without as well.
-?
a potential minus for negative numbers
\d+
any sequence of digits (at least one)
(?:[\./]\d+)?
an optional non-capturing group consisting of either a dot (note that you don't need to escape it here, it's just for consistency) or a slash followed by at least one more digit.
Update
If you don't want to replace "numbers" like .1234
, 1234.
/1
or 5/
(a digit is missing either left or right), try this expression: (?>(?<![\d\./])-?\d+(?:(?:[\./]\d+)|(?![\d\./])))
Here's a breakdown again:
The encloseing (?>...)
is an atomic group to prevent catastrophic backtracking. For simple or short strings it would work without as well.
(?<![\d\./])
the match must not directly follow a digit, dot or slash - note that the not follow a digit constraint is needed to match at the start of the number, otherwise you'd match 234
in .1234
-?
a potential minus for negative numbers
\\d+
any sequence of digits (at least one)
(?:(?:[\./]\d+)|(?![\d\./]))
the match must either have a dot or slash followed by at least one digit or must not be followed by a digit, dot or slash, this would match 1.0
but not 1.
- note that the not to be followed by a digit constraint is needed to prevent matching 123
in 1234.