Regex to truncate trailing zeroes - java

I'm trying to construct a single regex (for Java) to truncate trailing zeros past the decimal point. e.g.
50.000 → 50
50.500 → 50.5
50.0500 → 50.05
-5 → -5
50 → 50
5.5 → 5.5
Idea is to represent the real number (or integer) in the most compact form possible.
Here's what I've constructed:
^(-?[.0-9]+?)\.?0+$
I'm using $1 to capture the truncated number string.
The problem with the pattern above is that 50 gets truncated to 5. I need some way to express that the 0+ must follow a . (decimal point).
I've tried using negative-behind, but couldn't get any matches.

The best solution could be using built-in language-specific methods for that task.
If you cannot use them, you may use
^(-?\d+)(?:\.0+|(\.\d*?)0+|\.+)?$
And replace with $1$2.
See the regex demo. Adjust the regex accordingly. Here is the explanation:
^ - start of string
(-?\d+) -Group 1 capturing 1 or 0 minus symbols and then 1 or more digits
(?:\.0+|(\.\d*?)0+|\.+)? - An optional (matches 1 or 0 times due to the trailing ?) non-capturing group matching 3 alternatives:
\.0+ - a decimal point followed with 1+ zeros
(\.\d*?)0+ - Group 2 capturing a dot with any 0+ digits but as few as possible and matching 1+ zeros
\.+ - (optional branch, you may remove it if not needed) - matches the trailing dot(s)
$ - end of string.
Java demo:
String s = "50.000\n50\n50.100\n50.040\n50.\n50.000\n50.500\n50\n-5";
System.out.println(s.replaceAll("(?m)^(-?\\d+)(?:\\.0+|(\\.\\d*?)0+|\\.+)?$", "$1$2"));
// => [50, 50, 50.1, 50.04, 50, 50, 50.5, 50, -5]

For a general regex which should do the trick:
^\d+?0*\.??\d*?(?=0*?[^\d]*$)
You can replace the caret and dollar sign with whatever your boundaries should be. Those could be replaced by whatever you would expect around your number.
basically:
/d+? non-greedy match for any number (needs at least 1 number to start the match)
\.*?? optional match for a decimal. Prefers to match 0 occurrences
\d*? (?=0*?[^\d]*$) - non-greedy match for a number, but would stop at the 0 which is proceeded by a non-number
EDIT: I just realized the original expression also trimmed the last zero on integers, this should work. I added the option 0 match to catch that

Related

Pattern Matcher valid number java

I want to have a number validation. Rules are:
A number can start with + or - or nothing (it is taken as a positive number)
Cannot start with 0
Can have a fraction either . or ,
Cannot end with 0
So acceptable numbers are: +123, -123, 123, 1023, 123.03, 123,03.
Non acceptable numbers are: 001, 1.000, any letters
I give you the expression that I ve built so far, on Dan's Tools. I have managed almost everything, except expressions after the the fraction. Every help is acceptable.
Expression: (^(\+|-?)([1-9]+))([0-9]+)(\.|,?)
Thanks in advance
Nikos
Except the fractional part that is missing in your pattern, your regex won't match single digit numbers as you quantified [1-9] and [0-9] with + quantifier requiring at least one char.
You can use
^[+-]?[1-9][0-9]*(?:[.,][0-9]*[1-9])?$
See the regex demo and the regex graph:
Details
^ - start of string
[+-]? - an optional + or -
[1-9] - a single non-zero digit
[0-9]* - zero or more digits
(?:[.,][0-9]*[1-9])? - an optional fractional part: . or , and then zero or more digits followed with a single non-zero digit
$ - end of string.

Regex for latitude with required 6 decimal places

I need a regex in Java that will check if a String representation of a double has required 6 decimal places. Before the decimal point, value can be positive or negative.
1.123456 - correct
-123123123.123456 - correct
123123123.123456 - correct
-123123123.123456 - correct
1.12345 - wrong
-.123456 - wrong
.123456 - wrong
.12345 - wrong
123456 - wrong
I tried:
^\s*(?=.*[1-9])\d*(\.\d{6})?\s*$
but it doesn't cover all edges.
Try this:
^\s*(-|\+)?(0|[1-9]\d*)\.\d{6}\s*$
See live demo.
This allows the first digits to be zero only if it's the only digit before the dot, eg 0.123456 is OK, but not 01.123456. \.\d{6} requires exactly 6 decimal places.
The valid input should
start with optional whitespaces --->^\s*
then optional - or +--->(-|\+)?
then one or multiple digits--->\d+
then one dot ---> .
then six digits --->(\d{6})
end with optional whitespaces --->^\s*
Try this:
^\s*(-|\+)?\d+\.(\d{6})\s*$
In your regex the positive lookahead (?=.*[1-9]) asserts that what is on the right side should contain a digit which will succeed for all examples. After that assertion you match zero or more digits \d* followed by a part that optionally matches a dot and 6 digits (\.\d{6})? so this will match .588888 or also 1.
If you want to match an optional minus sign you could use -?
For your example data you might use:
^-?\d+\.\d{6}$
In Java:
String regex = "^-?\\d+\\.\\d{6}$";
Explanation
^ Assert the start of the line
-? Match an optional minus sign
\d+\.\d{6} Match one or more digits, a dot and 6 digits
$ Assert the end of the line
Demo

Regex to allow only 10 or 16 digit comma separated number

I want to validate a textfield in a Java based app where I want to allow only comma separated numbers and they should be either 10 or 16 digits. I have a regex that ^[0-9,;]+$ to allow only numbers, but it doesn't work for 10 or 16 digits only.
You can use {n,m} to specify length.
So matching one number with either 10 or 16 digits would be
^(\d{10}|\d{16})$
Meaning: match for exactly 10 or 16 digits and the stuff before is start-of-line and the stuff behind is end-of-line.
Now add separator:
^((\d{10}|\d{16})[,;])*(\d{10}|\d{16})$
Some sequences of 10-or-16 digit followed by either , or ; and then one sequece 10-or-16 with end-of-line.
You need to escape those \ in java.
public static void main(String[] args) {
String regex = "^((\\d{10}|\\d{16})[,;])*(\\d{10}|\\d{16})$";
String y = "0123456789,0123456789123456,0123456789";
System.out.println(y.matches(regex)); //Should be true
String n = "0123456789,01234567891234567,0123456789";
System.out.println(n.matches(regex)); //should be false
}
I would probably use this regex:
(\d{10}(?:\d{6})?,?)+
Explanation:
( - Begin capture group
\d{10} - Matching at least 10 digits
(?: - Begin non capture group
\d{6} - Match 6 more digits
)? - End group, mark as optional using ?
,? - optionally capture a comma
)+ - End outer capture group, require at least 1 or more to exist? (mabye change to * for 0 or more)
The following inputs match this regex
1234567890123456,1234567890
1234567890123456
1234567890
these inputs do not match
123,1234567890
12355
123456789012
You need to have both anchors and word boundaries:
/^(?:\b(?:\d{10}|\d{16})\b,?)*$/
The anchors are necessary so you don't get false positives for partial matches and the word boundaries are necessary so you don't get false positives for 20, 26, 30, 32 digit numbers.
Here is my version
(?:\d+,){9}\d+|(?:\d+,){15}\d+
Let's review it. First of all there is a problem to say: 10 or 16. So, I have to create actually 2 expressions with | between them.
Second, the expression itself. Your version just says that you allow digits and commas. However this is not what you really want because for example string like ,,, will match your regex.
So, the regex should be like (?:\d+,){n}\d+ that means: sequence of several digits terminated by comma and then sequence of several digits, e.g. 123,45,678 (where 123,45 match the first part and 678 match the second part)
Finally we get regex that I have written in the beginning of my answer:
(?:\d+,){9}\d+|(?:\d+,){15}\d+
And do not forget that when you write regex in you java code you have to duplicate the back slash, like this:
Pattern.compile("\\d+,{9}\\d+|\\d+,{15}\\d+")
EDIT: I have just added non-capturing group (?: ...... )

Matching numbers with regex

I need to match numbers where the first character is either a
- (minus) or NOT a 0 (unless it's the only character in the string) and I'm kinda stuck. ^[-|1-9]?[0-9]+ I've currently got this but it'll match any amount of zeroes.
Examples:
Should match:
-16
25
2005
Should not match:
-05
05
00001
0-017
Try a pattern like this:
^-?[1-9][0-9]*$
This will match optional - at the start of the string, followed by a single digit from 1 to 9, followed by zero or more digits from 0 to 9. The start (^) and end ($) anchors ensure that no other characters are allowed before or after the number.
Demonstration
Update It has been pointed out that the above pattern will match any positive or negative decimal integer without leading zeros, but it will not match zero, itself. To handle that case, add an alternation to your pattern like this:
^-?[1-9][0-9]*$|^0$
Or like this:
^(-?[1-9][0-9]*|0)$

Regex expression for timestamp with or without leading zero?

I'm struggling with Regex.
This is a sample timestamp: 00:00:00.00 (Hour, Minutes, Second.Decimal). I also want this value to match 00:0:0.00 Notice that the leasing zero is optional in the center.
I was using this: [1-60]:[1-60]:[1-60].[1-100], but that requires no leading zero. I would like help with making a SINGLE regex that works for both of the things listed above.
A complete solution would be fantastic, but if you could just point me in the right direction, that would be helpful as well.
Your solution won't actually match what you've described; it will only match a single digit in the sequence 0123456 in each position. You probably want something like
[0-5]?\d:[0-5]?\d:[0-5]?\d\.\d{1,2}
Your pattern has a number of other problems. [1-60] is a character class. It will match a single 1, 2, 3, 4, 5, 6, or 0 character. Secondly, the . in your pattern matches any character not just a literal ..
I think what you're looking for is something like this instead:
\d{1,2}:\d{1,2}:\d{1,2}\.\d{1,2}
This will match any one or two digits, followed by a literal :, followed by any one or two digits, followed by a literal :, followed by any one or two digits, followed by a literal ., followd by any one or two digits.
Or to check match only particular ranges of each time component, you can use a pattern like what chrylis suggests, although I'd generally recommend actually parsing the time value if you really need to do this.
Another option you could do:
(?:\d{1,2}:){2}\d{1,2}\.\d{1,2}
Regular expression:
(?: group, but do not capture (2 times):
\d{1,2} digits (0-9) (between 1 and 2 times)
: ':'
){2} end of grouping
\d{1,2} digits (0-9) (between 1 and 2 times)
\. '.'
\d{1,2} digits (0-9) (between 1 and 2 times)

Categories

Resources