Rewriting RegEx to be used in Java - java

I have written (?<=pp_).*(?=') regex to match what comes after pp_ in strings like
['newPage', 'pp_vii', -1]
My regex works fine in online testers (see online regex validator) but it won't in Java. My failing code:
Pattern pattern = Pattern.compile("(?<=pp_).*(?=')");
String input = "['newPage', 'pp_vii', -1])";
Matcher m = pattern.matcher(input);
boolean match = m.matches(); // false

The matches() method check for full string match so instead of that use find() method which checks for subsequence match. Finally, you can use group() method to get matched subsequence string.
public static void main(String[] args) {
Pattern pattern = Pattern.compile("(?<=pp_).*(?=')");
String input = "['newPage', 'pp_vii', -1])";
Matcher m = pattern.matcher(input);
boolean a = m.find();
if(a){
String out = m.group();
System.out.println("Match : " + out);
}

Your Regex is fine. The Matcher.matches() method only returns true, if the complete String matches the pattern (docs). You should use Matcher.find() instead. That finds the next subsequence that matches the pattern (docs).
Pattern pattern = Pattern.compile("(?<=pp_).*(?=')");
String input = "['newPage', 'pp_vii', -1])";
Matcher m = pattern.matcher(input);
boolean stringMatches = m.matches(); // false
boolean isThereMatch = m.find(); // true
System.out.println(isThereMatch + " " + stringMatches);
System.out.println(m.group());
That prints:
true false
vii

Related

I Want to extract a certain number from string in java but not able to do so

I have a string like String a = "I have 102 string but 123453 is best"
So, In the above string i want to extract only 123453
This string keep getting changes but i always want to get that second number from this string.
What is the best possible way to do this?
Here is a complete example. First define your pattern:
Pattern p = Pattern.compile("[0-9]+");
Then define the string you want to test
String test = "I have 102 string but 123453 is best";
Create a matcher for that string
Matcher matcher = p.matcher(test);
Find once
matcher.find(); // find once
Find again, and if found, get the string
if (matcher.find()) { // find twice
System.out.println(matcher.group());
}
For a complete, minimal and repeatable example, consider defining a method and defining the pattern as a constant:
static final Pattern P = Pattern.compile("[0-9]+");
static String findSecondNumber(String test) {
Matcher matcher = P.matcher(test);
matcher.find(); // find once
if (matcher.find()) { // find twice
return matcher.group();
}
return null; // or alternatively return an empty string or a default value
}
Where matcher.group() returns the full match found; see also the documentation here.
It can be done in a single find() with capturing groups. Here is how:
String a = "I have 102 string but 123453 is best"
Pattern p = Pattern.compile("^.*\d+.*(\d*).*$");
Matcher m = p.matcher(a);
if (m.find()) {
System.out.println(m.group(1)); // this will print 123453
}

Java : RegEx to find a substring Collection

I am using below java program to find list of js files as a Substring.
String str = "jsLib//connect.facebook.net/en_US/fbevents.js , jsLib//connect.facebook.net/en_US/fbevents2.js;";
String patternStr = "(\\/.*?\\.js)";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(html);
if (matcher.find()) {
System.out.println("Count:" + matcher.groupCount());
jsLib = matcher.group(1);
jsLib = jsLib.substring(jsLib.lastIndexOf('/') + 1, jsLib.length());
System.out.println("jsLib:" + jsLib);
}
Regex : I used String patternStr="(\\/.*?\\.js)";
Expected Result : both fbevents.js and fbevents2.js should be matched and part of result
Actual Result : only fbevents.js is matched
You may get all your results using while loop and a regex like [^/]*\.js:
String str = "jsLib//connect.facebook.net/en_US/fbevents.js , jsLib//connect.facebook.net/en_US/fbevents2.js;";
String patternStr = "[^/]*\\.js";
Pattern pattern = Pattern.compile(patternStr);
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println("jsLib:" + matcher.group());
}
Output:
jsLib:fbevents.js
jsLib:fbevents2.js
See the Java demo and the regex demo.
The [^/]*\.js pattern matches any 0+ chars other than / (with [^/]*) and then a .js substring.

regular expression to match a string in order

I have string as follows
"ValueFilter("val1") AND ColumnFilter("val2") AND ValueFilter("val3")"
I have stored the following regex in a array. Using for loop I tried to match the pattern
"ValueFilter\\((.*?)\\)","ColumnFilter\\((.*?)\\)"
what I will do is I will replace the value in the bracket and copy it to a new string.
When I run this above regex against the string in the first loop i have XFilter so it will match both occurrence. But I want to do this in order.
Here is the i thing i want to achieve
first i want to match ValueFilter first then ColumnFilter then again ValueFilter. How can I achieve this?
Edit : Added Code
String expr = "\"ValueFilter(\"val1\") AND ColumnFilter(\"val2\") AND ValueFilter(\"val3\")\"";
String patterns = {"ValueFilter\\((.*?)\\)", "ColumnFilter\\((.*?)\\)"}
for (String pattern : patterns) {
Pattern r = Pattern.compile(pattern);
Matcher m = r.matcher(expr);
while (m.find()) {
//do something
}
}
Expected Output
ValueFilter("val1")
ColumnFilter("val2")
ValueFilter("val3")
You can use this regex [XY]Filter\((.*?)\) with pattern and you have to loop throw the matches using :
String str = "\"XFilter(\"val1\") AND YFilter(\"val2\") AND XFilter(\"val3\")\"";
String regex = "[XY]Filter\\((.*?)\\)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group());
}
Note you can i use [XY] which mean to match both X or Y,
Output
XFilter("val1")
YFilter("val2")
XFilter("val3")
regex demo
If you want to get only the value you can get the group 1 like matcher.group(1) instead, the output should be :
"val1"
"val2"
"val3"
Edit
what if I have filtername as "ValueFilter" and "ColumnFilter" instead
of X and Y
In this case you can use (Value|Column) instead of [XY] which mean match ValueFilter or ColumnFilter, the regex should look like :
String str = "\"ValueFilter(\"val1\") AND ColumnFilter(\"val2\") AND ValueFilter(\"val3\")\"";
String regex = "(Value|Column)Filter\\((.*?)\\)";
Pattern pattern = Pattern.compile(regex);
Matcher matcher = pattern.matcher(str);
while (matcher.find()) {
System.out.println(matcher.group());
}
Output
ValueFilter("val1")
ColumnFilter("val2")
ValueFilter("val3")
Check code demo

Find multiple string matches using Java regex

I am trying to use regex to find a match for a string between Si and (P) or Si and (I).
Below is what I wrote. Why isn't it working and how do I fix it?
String Channel = "Si0/4(I) Si0/6( Si0/8K Si0/5(P)";
if (Channel.length() > 0) {
String pattern1 = "Si";
String pattern2 = "(P)";
String pattern3 = "(I)";
String P1 = Pattern.quote(pattern1) + "(.*?)[" + Pattern.quote(pattern2) + "|" + Pattern.quote(pattern3) + "]";
Pattern p = Pattern.compile(P1);
Matcher m = p.matcher(Channel);
while(m.find()){
if (m.group(1)!= null)
{
System.out.println(m.group(1));
}
else if (m.group(2)!= null)
{
System.out.println(m.group(2));
}
}
}
Expected output
0/4
0/5
Actual output
0/4
0/6
0/8K Si0/5
Use a lookbehind and lookahead in your regex. And also you need to add space inside the character class, so that it won't this 0/8K string .
(?<=Si)[^\\( ]*(?=\\((?:P|I)\\))
DEMO
String str="Si0/4(I) Si0/6( Si0/8K Si0/5(P)";
String regex="(?<=Si)[^\\( ]*(?=\\([PI]\\))";
Pattern pattern = Pattern.compile(regex);
Matcher matcher =pattern.matcher(str);
while(matcher.find()){
System.out.println(matcher.group(0));
}
Output:
0/4
0/5
You need to group your regex.It is currently
Si(.*?)[(P)|(I)]
Whereas it should be
Si(.*?)\(I\)|Si(.*?)\(P\)
See demo.
http://regex101.com/r/oO8zI4/8
[] means "any of these character", so it evaluates every letter in the block as if they were separated with OR.
If the result you're searching is always: number/number
You can use:
Si(\d+\/\d+)(?:\(P\)|\(I\))

Get an array of Strings matching a pattern from a String

I have a long string let's say
I like this #computer and I want to buy it from #XXXMall.
I know the regular expression pattern is
Pattern tagMatcher = Pattern.compile("[#]+[A-Za-z0-9-_]+\\b");
Now i want to get all the hashtags in an array. How can i use this expression to get array of all hash tags from string something like
ArrayList hashtags = getArray(pattern, str)
You can write like?
private static List<String> getArray(Pattern tagMatcher, String str) {
Matcher m = tagMatcher.matcher(str);
List<String> l = new ArrayList<String>();
while(m.find()) {
String s = m.group(); //will give you "#computer"
s = s.substring(1); // will give you just "computer"
l.add(s);
}
return l;
}
Also you can use \\w- instead of A-Za-z0-9-_ making the regex [#]+[\\w]+\\b
This link would surely be helpful for achieving what you want.
It says:
The find() method searches for occurrences of the regular expressions
in the text passed to the Pattern.matcher(text) method, when the
Matcher was created. If multiple matches can be found in the text, the
find() method will find the first, and then for each subsequent call
to find() it will move to the next match.
The methods start() and end() will give the indexes into the text
where the found match starts and ends.
Example:
String text =
"This is the text which is to be searched " +
"for occurrences of the word 'is'.";
String patternString = "is";
Pattern pattern = Pattern.compile(patternString);
Matcher matcher = pattern.matcher(text);
int count = 0;
while(matcher.find()) {
count++;
System.out.println("found: " + count + " : "
+ matcher.start() + " - " + matcher.end());
}
You got the hint now.
Here is one way, using Matcher
Pattern tagMatcher = Pattern.compile("#+[-\\w]+\\b");
Matcher m = tagMatcher.matcher(stringToMatch);
ArrayList<String> hashtags = new ArrayList<>();
while (m.find()) {
hashtags.add(m.group());
}
I took the liberty of simplifying your regex. # does not need to be in a character class. [A-Za-z0-9_] is the same as \w, so [A-Za-z0-9-_] is the same as [-\w]
You can use :
String val="I like this #computer and I want to buy it from #XXXMall.";
String REGEX = "(?<=#)[A-Za-z0-9-_]+";
List<String> list = new ArrayList<String>();
Pattern pattern = Pattern.compile(REGEX);
Matcher matcher = pattern.matcher(val);
while(matcher.find()){
list.add(matcher.group());
}
(?<=#) Positive Lookbehind - Assert that the character # literally be matched.
you can use the following code for getting the names
String saa = "#{akka}nikhil#{kumar}aaaaa";
Pattern regex = Pattern.compile("#\\{(.*?)\\}");
Matcher m = regex.matcher(saa);
while(m.find()) {
String s = m.group(1);
System.out.println(s);
}
It will print
akka
kumar

Categories

Resources