Is there a regular expression that will capture all instances of an expression, regardless of whether or not they overlap?
E.g. in /abc/def/ghi if I want to capture all strings beginning with /. The regex (/.*) only returns the entire string, but I'd want it to match on /def/ghi and /ghi as well.
Sure, match an empty string and place a look-ahead after it that captures /.* in a capturing group:
Matcher m = Pattern.compile("(?=(/.*))").matcher("/abc/def/ghi");
while(m.find()) {
System.out.println(m.group(1));
}
would print:
/abc/def/ghi
/def/ghi
/ghi
Related
My requirements include among other things to validate for the password input to include one of the following characters only once. !##$%^&*()_+=?~
To accomplish that I wrote the following:
StringBuilder builder = new StringBuilder("(?=.*[a-z])");
builder.append("(?=.{1}[!##$%^&*()_+=?~])");
Pattern pattern = Pattern.compile(builder.toString());
Matcher matcher = pattern.matcher(input);
if(matcher.matches){
return True;
}
But this always fails when I pass valid input in my unit test. I am new to regex.
You may use this regex with 2 lookahead assertions:
^(?=[^a-z]*[a-z])(?=[^!##$%^&*()_+=?~]*[!##$%^&*()_+=?~][^!##$%^&*()_+=?~]*$).{12,}$
RegEx Demo
Note that in .matches() method start & end anchors are automatically implied in a given regex.
RegEx Details:
^: Start
(?=[^a-z]*[a-z]): Positive lookahead to make sure we have at least one lowercase letter
(?=[^!##$%^&*()_+=?~]*[!##$%^&*()_+=?~][^!##$%^&*()_+=?~]*$): Positive lookahead to make sure we have ONLY one of the given special character.
.{12,}: Match min 12 of any characters
$: End
I have an input containing repeated pattern like this:
(3,5)(6,7)(8,9).....
I am working on a regex to validate the above string pattern.
I tried:
Pattern.compile("\\((\\d+),(\\d+)\\)")
If you have a specific pattern that may repeat one or more times in a string, and you want to make sure your string only consists of the repeated occurrences of the same pattern, you may use
^(?:YOUR_PATTERN)+$
\A(?:YOUR_PATTERN)+\z
Note that $ also matches before a final newline char, that is why \z anchor is preferred when you need to match the very end of the string.
If you allow an empty string use the * quantifier instead of +:
^(?:YOUR_PATTERN)*$
\A(?:YOUR_PATTERN)*\z
In this case, the YOUR_PATTERN is \(\d+,\d+\), thus, the repeated sequence validating pattern will be \A(?:\(\d+,\d+\))+\z.
In Java, you may omit the ^/$ and \A/\z anchors when validating a string with .matches() method since it requires a full string match:
boolean isValid = text.matches("(?:\\(\\d+,\\d+\\))+");
Or, decalre the Pattern class instance first and then create a matcher with the string as input and run Matcher#matches()
Pattern p = Pattern.compile("(?:\\(\\d+,\\d+\\))+");
Matcher m = p.matcher(text);
if (m.matches()) {
// The text is valid!
}
I need to find two characters after the last underscore in given filename.
Example string:
sample_filename_AB12123321.pdf
I am using [^_]*(?=\.pdf), but it finds all the characters after the underscore like AB12123321.
I need to find the first two characters AB only.
Moreover, there is no way to access the code, I can only modify the regex pattern.
If you want to solve the problem using a regex you may use:
(?<=_)[^_]{2}(?=[^_]*$)
See regex demo.
Details
(?<=_) - an underscore must appear immediately to the left of the current position
[^_]{2} - Capturing group 1: any 2 chars other than underscore
(?=[^_]*$) - immediately to the left of the current position, there must appear any 0+ chars other than underscore and then an end of string.
See the Java demo:
String s = "sample_filename_AB12123321.pdf";
Pattern pattern = Pattern.compile("(?<=_)[^_]{2}(?=[^_]*$)");
Matcher matcher = pattern.matcher(s);
if (matcher.find()){
System.out.println(matcher.group(0));
}
Output: AB.
i'm trying to capture 2 things in a String "T3st12345"
I want to capture the trailing numbers ("12345") and also the name of the test "T3st".
This is what I have right now to match the trailing numbers with java's Matcher library:
Pattern pattern = Pattern.compile("([0-9]*$)");
Matcher matcher = pattern.matcher("T3st12345");
but it returns "no match found".
How can I make this work for the trailing numbers and how do I capture the name of the test as well?
You can use this regex with 2 captured groups:
^(.*?)(\d+)$
RegEx Demo
RegEx Breakup:
^: Start
(.*?): Captured group #1 that matches zero of any character (lazy)
(\d+): Captured group #1 that matches one or more digits before End
$: End
You may use the following regex:
Pattern pattern = Pattern.compile("(\\p{Alnum}+?)([0-9]*)");
Matcher matcher = pattern.matcher("T3st12345");
if (matcher.matches()) {
System.out.println(matcher.group(1));
System.out.println(matcher.group(2));
}
See the Java demo
The (\\p{Alnum}+?)([0-9]*) pattern is used in the .matches() method (to require a full string match) and matches and captures into Group 1 one or more alphanumeric chars, as few as possible (+? is a lazy quantifier), and captures into Group 2 any zero or more digits.
Note that \\p{Alnum} can be replaced with a more explicit [a-zA-Z0-9].
This question already has answers here:
Regex doesn't work in String.matches()
(9 answers)
Closed 5 years ago.
Here is my issue. I have this:
String data = "java.awt.Color[r=168,g=228,b=160]" //example this changes.
Pattern p = Pattern.compile("(\\d+)");
Matcher m = p.matcher(data);
if(m.matches()){
....
}
However, it is not matching. Why is that? I am trying to retrieve the numbers inside brackets.
What should I try?
Matcher.matches() matches the complete string. You can use Matcher.find to match the individual integers:
while (m.find()) {
System.out.println(m.group(1));
}
Matcher.matches tells you if your regex matches the entire string. Your string isn't all digits. It contains letters, dots, equal signs, and square brackets. So you matcher doesn't match.
You want Matcher.find(). That searches for partial matches. Matcher.group then allows you to retrieve the matched portion of the input string.
Note that the Matcher.matches() method attempts to match against the entire string.
You want to use Matcher.find() instead.
The matches method will attempt to match the regex against the entire input.
Use a combination of the the find and group methods method to find and use matches within the input:
while (m.find())
System.out.println(m.group());
Because your regex doesn't match the string, there are other characters before (and after) the \d matches after all.
matches() method attempts to match the whole string, but you need just digit occurrences in it.
You need to use find() method and you might need to use while operator instead of if because it shifts matcher to next match occurrence.