regex to strip leading zeros treated as string - java

I have numbers like this that need leading zero's removed.
Here is what I need:
00000004334300343 -> 4334300343
0003030435243 -> 3030435243
I can't figure this out as I'm new to regular expressions. This does not work:
(^0)

You're almost there. You just need quantifier:
str = str.replaceAll("^0+", "");
It replaces 1 or more occurrences of 0 (that is what + quantifier is for. Similarly, we have * quantifier, which means 0 or more), at the beginning of the string (that's given by caret - ^), with empty string.

Accepted solution will fail if you need to get "0" from "00". This is the right one:
str = str.replaceAll("^0+(?!$)", "");
^0+(?!$) means match one or more zeros if it is not followed by end of string.
Thank you to the commenter - I have updated the formula to match the description from the author.

If you know input strings are all containing digits then you can do:
String s = "00000004334300343";
System.out.println(Long.valueOf(s));
// 4334300343
Code Demo
By converting to Long it will automatically strip off all leading zeroes.

Another solution (might be more intuitive to read)
str = str.replaceFirst("^0+", "");
^ - match the beginning of a line
0+ - match the zero digit character one or more times
A exhausting list of pattern you can find here Pattern.

\b0+\B will do the work. See demo \b anchors your match to a word boundary, it matches a sequence of one or more zeros 0+, and finishes not in a word boundary (to not eliminate the last 0 in case you have only 00...000)

The correct regex to strip leading zeros is
str = str.replaceAll("^0+", "");
This regex will match 0 character in quantity of one and more at the string beginning.
There is not reason to worry about replaceAll method, as regex has ^ (begin input) special character that assure the replacement will be invoked only once.
Ultimately you can use Java build-in feature to do the same:
String str = "00000004334300343";
long number = Long.parseLong(str);
// outputs 4334300343
The leading zeros will be stripped for you automatically.

I know this is an old question, but I think the best way to do this is actually
str = str.replaceAll("(^0+)?(\d+)", "$2")
The reason I suggest this is because it splits the string into two groups. The second group is at least one digit. The first group matches 1 or more zeros at the start of the line. However, the first group is optional, meaning that if there are no leading zeros, you just get all of the digits. And, if str is only a zero, you get exactly one zero (because the second group must match at least one digit).
So if it's any number of 0s, you get back exactly one zero. If it starts with any number of 0s followed by any other digit, you get no leading zeros. If it starts with any other digit, you get back exactly what you had in the first place.

Here is the simple and proper solution.
str = str.replaceAll(/^0+/g, "");
Global Flag g is required when using replaceAll with regex

Related

Remove leading zeros from a string using regex

I am learning regex and java and working on a problem related to that.
I have an input string which can be any dollar amount like
$123,456.78
$0012,345.67
$123,04.56
$123,45.06
it also could be
$0.1
I am trying to find if the dollar amount has leading zeros and trying to remove it.
so far I have tried this
string result = input_string.replaceAll(("[!^0]+)" , "");
But I guess I'm doing something wrong.
I just want to remove the leading zeros, not the ones between the amount part and not the one in cents. And if the amount is $0.1, I don't want to remove it.
Match zeroes or commas that are preceded by a dollar sign and followed by a digit:
str = str.replaceAll("(?<=\\$)[0,]+(?=\\d)", "");
See live demo.
This covers the edge cases:
$001.23 -> $1.23
$000.12 -> $0.12
$00,123.45 -> $123.45
$0,000,000.12 -> $0.12
The regex:
(?<=\\$) means the preceding character is a dollar sign
(?=\\d) means the following character is a digit
[0,]+ means one or more zeroes or commas
To handle any currency symbol:
str = str.replaceAll("(?<=[^\\d,.])[0,]+(?=\\d)", "");
See live demo.
You can use
string result = input_string.replaceFirst("(?<=\\p{Sc})[0,]+(?=\\d)", "");
See the regex demo.
Details:
(?<=\p{Sc}) - immediately on the left, there must be any currency char
[0,]+ - one or more zeros or commas
(?=\d) - immediately on the right, there must be any one digit.
This is a simple regex that fits your needs:
str = str.replaceAll("^[$][,0]+0(?![.])", "$");

Java Regex to replace only part of string (url)

I want to replace only numeric section of a string. Most of the cases it's either full URL or part of URL, but it can be just a normal string as well.
/users/12345 becomes /users/XXXXX
/users/234567/summary becomes /users/XXXXXX/summary
/api/v1/summary/5678 becomes /api/v1/summary/XXXX
http://example.com/api/v1/summary/5678/single becomes http://example.com/api/v1/summary/XXXX/single
Notice that I am not replacing 1 from /api/v1
So far, I have only following which seem to work in most of the cases:
input.replaceAll("/[\\d]+$", "/XXXXX").replaceAll("/[\\d]+/", "/XXXXX/");
But this has 2 problems:
The replacement size doesn't match with the original string length.
The replacement character is hardcoded.
Is there a better way to do this?
In Java you can use:
str = str.replaceAll("(/|(?!^)\\G)\\d(?=\\d*(?:/|$))", "$1X");
RegEx Demo
RegEx Details:
\G asserts position at the end of the previous match or the start of the string for the first match.
(/|(?!^)\\G): Match / or end of the previous match (but not at start) in capture group #1
\\d: Match a digit
(?=\\d*(?:/|$)): Ensure that digits are followed by a / or end.
Replacement: $1X: replace it with capture group #1 followed by X
Not a Java guy here but the idea should be transferrable. Just capture a /, digits and / optionally, count the length of the second group and but it back again.
So
(/)(\d+)(/?)
becomes
$1XYZ$3
See a demo on regex101.com and this answer for a lambda equivalent to e.g. Python or PHP.
First of all you need something like this :
String new_s1 = s3.replaceAll("(\\/)(\\d)+(\\/)?", "$1XXXXX$3");

Java regex negative lookahead to replace non-triple characters

I'm trying to take a number, convert it into a string and replace all characters that are not a triple.
Eg. if I pass in 1222331 my replace method should return 222. I can find that this pattern exists but I need to get the value and save it into a string for additional logic. I don't want to do a for loop to iterate through this string.
I have the following code:
String first = Integer.toString(num1);
String x = first.replaceAll("^((?!([0-9])\\3{2})).*$","");
But it's replacing the triple digits also. I only need it to replace the rest of the characters. Is my approach wrong?
You can use
first = first.replaceAll("((\\d)\\2{2})|\\d", "$1");
See regex demo
The regex - ((\d)\2{2})|\d - matches either a digit that repeats thrice (and captures it into Group 1), or just matches any other digit. $1 just restores the captured text in the resulting string while removing all others.

Regex allow ; and at least 5 digit numbers and trim leading/trailing semicolon in JAVA

This is what I am after:
Replace all characters that are not digits and not semicolon ; with nothing: "".
Numbers must be at least 5 digits long.
Trim leading and trailing semicolon ;
So:
567834 is valid
123456;654321;3456789 is valid
123;456 is not valid(too short numbers), will be replaced with empty string ""
;123456; will be trimmed to 123456
;567890 will be trimmed to 567890
456789; will be trimmed to 456789
I was thinking of using replaceAll method to do the work.
str.replaceAll("(\\d+\\;?)*\\d+", "");
But this doesn't take care of trimming leading and trailing semicolons and doesn't replace too short numbers with "".
Any help is appreciated!
I'd recommend breaking the problem into steps. This is an easy problem if you do. A single regex will be challenging, both to develop today and to read for every day after. Readable, easily understandable code should be your objective.
String trimmedStr = str.trim();
String noSemicolons = trimmedStr.replaceAll(";", "");
Matcher matcher = Pattern.compile("^\d{5,}$").matcher(noSemicolons);
boolean isValid = matcher.matches();
You can use:
String repl = input.replaceAll(";?\\b(\\d{5,})\\b;?|[\\d;]*", "$1");
RegEx Demo
You can use this replacement:
String result = input.replaceAll("(\\d{5,})|\\d{1,4}(?:;+|\\z)|;+\\d{0,4}\\z|\\A;", "$1");
The idea is to preserve numbers with at least 5 digits first in a capture group (because the first branch on the left that succeeds wins). Other branches describes what you need to remove.
An other way:
String result = input.replaceAll("((?:\\d{5,}(?:;(?!\\z))?)*+)(?:;*\\d{0,4}(?:;+|\\z))++", "$1");
This one describes the string as a succession of parts to remove preceded by an optional part to preserve.

Java Regex of String start with number and fixed length

I made a regular expression for checking the length of String , all characters are numbers and start with number e.g 123
Following is my expression
REGEX =^123\\d+{9}$";
But it was unable to check the length of String. It validates those strings only their length is 9 and start with 123.
But if I pass the String 1234567891 it also validates it. But how should I do it which thing is wrong on my side.
Like already answered here, the simplest way is just removing the +:
^123\\d{9}$
or
^123\\d{6}$
Depending on what you need exactly.
You can also use another, a bit more complicated and generic approach, a negative lookahead:
(?!.{10,})^123\\d+$
Explanation:
This: (?!.{10,}) is a negative look-ahead (?= would be a positive look-ahead), it means that if the expression after the look-ahead matches this pattern, then the overall string doesn't match. Roughly it means: The criteria for this regular expression is only met if the pattern in the negative look-ahead doesn't match.
In this case, the string matches only if .{10} doesn't match, which means 10 or more characters, so it only matches if the pattern in front matches up to 9 characters.
A positive look-ahead does the opposite, only matching if the criteria in the look-ahead also matches.
Just putting this here for curiosity sake, it's more complex than what you need for this.
Try using this one:
^123\\d{6}$
I changed it to 6 because 1, 2, and 3 should probably still count as digits.
Also, I removed the +. With it, it would match 1 or more \ds (therefore an infinite amount of digits).
Based on your comment below Doorknobs's answer you can do this:
int length = 9;
String prefix = "123"; // or whatever
String regex = "^" + prefix + "\\d{ " + (length - prefix.length()) + "}$";
if (input.matches(regex)) {
// good
} else {
// bad
}

Categories

Resources