Extract any 5 digit number from a String using Java - java

I'm attempting to use REGEX to pull a 5 digit number from a larger String.
Here is the method I am using to do this however it simply returns null.
public void setCWBudgetCode(String webPage){
Pattern pattern = Pattern.compile("/\\b\\d{5}\b/g");
Matcher matcher = pattern.matcher(webPage);
if (matcher.find())
this.cwBudgetCode = matcher.group();
}

This is the problem:
Pattern pattern = Pattern.compile("/\\b\\d{5}\\b/g");
Instead of that use this pattern:
Pattern pattern = Pattern.compile("(\\b\\d{5}\\b)");
Unlike Javascript there is no regex delimiter in Java and of course no /g
Also note I have use parenthesis around regex so that you can use matcher.group(1)

You need to change your Regex to save the number as a group Pattern.compile("\\b(\\d{5})\\b");
this will make it work with your group(1) code below

Related

Java regex, replace certain characters except

I have this string "u2x4m5x7" and I want replace all the characters but a number followed by an x with "".
The output should be:
"2x5x"
Just the number followed by the x.
But I am getting this:
"2x45x7"
I'm doing this:
String string = "u2x4m5x7";
String s = string.replaceAll("[^0-9+x]","");
Please help!!!
Here is a one-liner using String#replaceAll with two replacements:
System.out.println(string.replaceAll("\\d+(?!x)", "").replaceAll("[^x\\d]", ""));
Here is another working solution. We can iterate the input string using a formal pattern matcher with the pattern \d+x. This is the whitelist approach, of trying to match the variable combinations we want to keep.
String input = "u2x4m5x7";
Pattern pattern = Pattern.compile("\\d+x");
Matcher m = pattern.matcher(input);
StringBuilder b = new StringBuilder();
while(m.find()) {
b.append(m.group(0));
}
System.out.println(b)
This prints:
2x5x
It looks like this would be much simpler by searching to get the match rather than replacing all non matches, but here is a possible solution, though it may be missing a few cases:
\d(?!x)|[^0-9x]|(?<!\d)x
https://regex101.com/r/v6udph/1
Basically it will:
\d(?!x) -- remove any digit not followed by an x
[^0-9x] -- remove all non-x/digit characters
(?<!\d)x -- remove all x's not preceded by a digit
But then again, grabbing from \dx would be much simpler
Capture what you need to $1 OR any character and replace with captured $1 (empty if |. matched).
String s = string.replaceAll("(\\d+x)|.", "$1");
See this demo at regex101 or a Java demo at tio.run

Java regex matcher doesn't group as expected

I have a regex
.*?(\\d+.*?\\d*).*?-.*?(\\d+.*?\\d*).*?
I want to match any string that contains a numerical value followed by "-" and another number. Any string can be in between.
Also, I want to be able to extract the numbers using group function of Java Matcher class.
Pattern pattern = Pattern.compile(".*?(\\d+.*?\\d*).*?-.*?(\\d+.*?\\d*).*?");
Matcher matcher = pattern.matcher("13.9 mp - 14.9 mp");
matcher.matches();
I expect this result:
matcher.group(1) // this should be 13.9 but it is 13 instead
matcher.group(2) // this should be 14.9 but it is 14 instead
Any idea what I am missing?
Your current pattern has several problems. As others have pointed out, your dots should be escaped with two backslashes if you intend for them to be literal dots. I think the pattern you want to use to match a number which may or may not have a decimal component is this:
(\\d+(?:\\.\\d+)?)
This matches the following:
\\d+ one or more numbers
(?:\\.\\d+)? followed by a decimal point and one or more numbers
this entire quantity being optional
Full code:
Pattern pattern = Pattern.compile(".*?(\\d+(?:\\.\\d+)?).*?-.*?(\\d+(?:\\.\\d+)?).*?");
Matcher matcher = pattern.matcher("13.9 mp - 14.9 mp");
while (matcher.find()) {
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
}
Output:
13.9
14.9
.*?(\d+\.*\d*).*?-.*?(\d+\.*\d*).*?
. between '\d+' and '\d' in your regex should be changed to \.

Regex to match words after forward slash or in between

I have this code that needs to get words after / or in between this character.
Pattern pattern = Pattern.compile("\\/([a-zA-Z0-9]{0,})"); // Regex: \/([a-zA-Z0-9]{0,})
Matcher matcher = pattern.matcher(path);
if(matcher.matches()){
return matcher.group(0);
}
The regex \/([a-zA-Z0-9]{0,}) works but not in Java, what could be the reason?
You need to get the value of Group 1 and use find to get a partial match:
Pattern pattern = Pattern.compile("/([a-zA-Z0-9]*)");
Matcher matcher = pattern.matcher(path);
if(matcher.find()){
return matcher.group(1); // Here, use Group 1 value
}
Matcher.matches requires a full string match, only use it if your string fully matches the pattern. Else, use Matcher.find.
Since the value you need is captured into Group 1 (([a-zA-Z0-9]*), the subpattern enclosed with parentheses), you need to return that part.
You needn't escape the / in Java regex. Also, {0,} functions the same way as * quantifier (matches zero or more occurrences of the quantified subpattern).
Also, [a-zA-Z0-9] can be replaced with \p{Alnum} to match the same range of characters (see Java regex syntax reference. The pattern declaration will look like
"/(\\p{Alnum}*)"

Grouping multiple digits prior to a known value

I'm executing this regex code expecting a grouping value of 11, but am getting a 1. Seems like the grouping contains the correct regex for getting one or more digits prior to a known value. I'm sure it is simple, bit I cannot seem to figure it out.
String mydata = "P0Y0M0W0DT11H0M0S";
Pattern pattern = Pattern.compile("P.*(\\\\d+)H.*");
Matcher matcher = pattern.matcher(mydata);
if (matcher.find()){
System.out.println(matcher.group(1));
}
Try this
public static void main(String a1[]) {
String mydata = "P0Y0M0W0DT11H0M0S";
Pattern pattern = Pattern.compile("P.*?(\\d+)H.*");
Matcher matcher = pattern.matcher(mydata);
if (matcher.find()){
System.out.println(matcher.group(1));
}
}
Output
11
The problem is that .* will try to consume/match as much as possible before the next part is checked. Thus in your regex P.*(\d+)H.* the first .* will match 0Y0M0W0DT1 since that's as much as can be matched with the group still being able to match a single digit afterwards.
If you make that quantifier lazy/reluctant (i.e. .*?), it will try to match as little as possible so of the possible matches 0Y0M0W0DT1 and 0Y0M0W0DT it will select the shorter one and leave all the digits for the group to match.
Thus the regex P.*?(\d+)H.* should do what you want.
Additional note: since you're using Matcher#find() you'd not need the catch-all-expression .* at the end. It would also match any string that contains the character H preceeded by at least one digit and a P somewhere in front of those digits. So if you want to be more restrictive your regex would need to be enhanced.

Java conditional regex

I have such text:
120.65UAH Produkti Kvartal
5*14 14:24
Bal. 16603.52UAH
What I want to do:
If this text contains "5*14", I need to get 16603.52 via one java reg exp.
this
and this
and this
I tried to create conditional regexp like this:
(5*14 ([\d\.*]+)UAH)
(5*14 d{2}:d{2} Bal. ([\d\.*]+))
etc
But no luck, can you please share your th
You can use a regex like this:
(?=5\*14)[\s\S]*?(\d{5}\.\d{2})
Working demo
Update: you even don't need the look ahead, you can just use:
5\*14[\s\S]*?(\d{5}\.\d{2})
(\d*\.\d\d)(?>\w*)$
will match a group on the last set of DDDDD.DD in the line. You will need to take the contents of the first matching group.
If you have 5*14 before the float number you need to get, you can just use
(?s)\\b5\\*14\\b.*?\\b(\\d+\\.\\d+)
See demo. The value will be in Group 1. I also used Java escaping style.
Note that 5\*14 can match in 145*143 that is why I am using word boundaries \b. .*? with (?s) matches any number of any symbols but as few as possible. \d+\.\d+ matches simple float number (irrespective of the number of digits there are in it).
IDEONE demo:
String str = "120.65UAH Produkti Kvartal\n5*14 14:24\nBal. 16603.52UAH";
Pattern ptrn = Pattern.compile("(?s)\\b5\\*14\\b.*?\\b(\\d+\\.\\d+)");
Matcher matcher = ptrn.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group(1));
}
Result: 16603.52

Categories

Resources