Pattern Matching with dynamic matcher - java

Sample input string : Customer ${/xml:Name} has Ordered Product ${/xml:product} of ${/xml:unit} units.
i able to find get strings that match ${ ...... } using "\\$\\{.*?\\}"
I resolve the value for string from xml and now i have to replace the value back in input string.
i am using this method,
Pattern MY_PATTERN = Pattern.compile("\\$\\{.*?\\}");
Matcher m = MY_PATTERN.matcher(inputstring);
while (m.find()) {
String s = m.group(0); // s is ${/xml:Name}
// escaping wild characters
s = s.replaceAll("${", "\\$\\{"); // s is \$\{/xml:Name}
s = s.replaceAll("}", "\\}"); // s is \$\{/xml:Name\}
Pattern inner_pattern = Pattern.compile(s);
Matcher m1 = inner_pattern.matcher(inputstring);
name = m1.replaceAll(xPathValues.get(s));
}
but i get error at s = s.replaceAll("${", "\\$\\{"); i get Pattern Syntax Exception

You must escape the { too, try $\\{

Instead of:
s = s.replaceAll("${", "\\$\\{"); // s is \$\{/xml:Name}
s = s.replaceAll("}", "\\}"); // s is \$\{/xml:Name\}
You can use it without regex method String#replace(string):
s = s.replace("${", "\\$\\{").replace("}", "\\}"); // s is \$\{/xml:Name\}

It's because you could have a regexp likea{1,4} means to match a,aa,aaa,aaaa so a times 1 to 4, java tries to interpret your regexp like this, therefore try escaping the {

Yes, you must escape the {, but I would rather capture what's inside the braces:
Pattern MY_PATTERN = Pattern.compile("\\$\\{/xml:(.*?)\\}");
Matcher m = MY_PATTERN.matcher(inputstring);
while (m.find()) {
name = m.group(1); // s is Name
...
}

Related

How to extract data using pattern and matcher

Hey i am trying to map old URLs to new url. Like -
/oldapp/viewReview.do?action=show_references&bugId=xy12&queueName=OLLD-CodeReviews
to - newapp/review/reference?bugId=xy12&queueName=OLLD-CodeReviews
How i can use Pattern and Matcher to match the pattern and extract bugId and queueName from URL. please help.
Any characters followed by ? or & followed by the identifier, =, and the value which cannot contain & as a group, and then any trailing characters:
Pattern bugidp = Pattern.compile(".*[?&]bugId=([^&]+).*");
Pattern queuep = Pattern.compile(".*[?&]queueName=([^&]+).*");
Matcher bugidm = bugidp.matcher(url);
Matcher queuem = queuep.matcher(url);
if (bugid.matches() && queuem.matches()) {
String bugid = bugidm.group(1);
String qname = queuem.group(1);
String newrl = String.format("newapp/review/reference?bugId=%s&queueName=%s",
bugid, qname);
} else {
// not found
}

Java regular expression to match parameters within a function

I would like to write a regular expression to extract parameter1 and parameter2 of func1(parameter1, parameter2), the length of parameter1 and parameter2 ranges from 1 to 64.
(func1) (\() (.{1,64}) (,\\s*) (.{1,64}) (\))
My version can not deal with the following case (nested function)
func2(func1(ef5b, 7dbdd))
I always get a "7dbdd)" for parameter2. How could I solve this?
Use "anything but closing parenthesis" ([^)]) instead of simply "anything" (.):
(func1) (\() (.{1,64}) (,\s*) ([^)]{1,64}) (\))
Demo: https://regex101.com/r/sP6eS1/1
Use [^)]{1,64} (match all except )) instead of .{1,64} (match any) to stop right before the first )
(func1) (\() (.{1,64}) (,\\s*) (.{1,64}) (\))
^
replace . with [^)]
Example:
// remove whitespace and escape backslash!
String regex = "(func1)(\\()(.{1,64})(,\\s*)([^)]{1,64})(\\))";
String input = "func2(func1(ef5b, 7dbdd))";
Pattern p = Pattern.compile(regex); // java.util.regex.Pattern
Matcher m = p.matcher(input); // java.util.regex.Matcher
if(m.find()) { // use while loop for multiple occurrences
String param1 = m.group(3);
String param2 = m.group(5);
// process the result...
}
If you want to ignore whitespace tokens, use this one:
func1\s*\(\s*([^\s]{1,64})\s*,\s*([^\s\)]{1,64})\s*\)"
Example:
// escape backslash!
String regex = "func1\\s*\\(\\s*([^\\s]{1,64})\\s*,\\s*([^\\s\\)]{1,64})\\s*\\)";
String input = "func2(func1 ( ef5b, 7dbdd ))";
Pattern p = Pattern.compile(regex); // java.util.regex.Pattern
Matcher m = p.matcher(input); // java.util.regex.Matcher
if(m.find()) { // use while loop for multiple occurrences
String param1 = m.group(1);
String param2 = m.group(2);
// process the result...
}
Hope this helpful
func1[^\(]*\(\s*([^,]{1,64}),\s*([^\)]{1,64})\s*\)
(func1) (\() (.{1,64}) (,\\s*) ([^)]{1,64}) (\))
^.*(func1)(\()(.{1,64})(,\s*)(.{1,64}[A-Za-z\d])(\))+
Working example: here

Matcher not finding matches

I'm trying to extract the numbers in the following string:
09/29/2014
I am currently using the code:
Pattern p = Pattern.compile("([0-9]{2})/([0-9]{2})/([0-9]{4})");
Matcher m = p.matcher(startDatepicker);
String startYear = m.group(3);
String startMonth = m.group(1);
String startDay = m.group(2);
startDatepicker contains: 09/29/2014
However, I am not receiving any matches.. I also tried escaping the forward slashes with \\ but that also didn't work.
Am I missing something?
Thanks for your help.
Before you could access the matched groups, you need to call find() on the matcher, and check that it has found a match:
Pattern p = Pattern.compile("([0-9]{2})/([0-9]{2})/([0-9]{4})");
Matcher m = p.matcher(startDatepicker);
if (!m.find()) {
return;
}
String startYear = m.group(3);
String startMonth = m.group(1);
String startDay = m.group(2);
The call of m.find() positions the matcher on the first match.
Demo.
You need to call find() to iterate through your match groups.
Pattern p = Pattern.compile("([0-9]{2})/([0-9]{2})/([0-9]{4})");
Matcher m = p.matcher(startDatepicker);
while (m.find()) {
...
}
The find() method searches for occurrences of the regex in the input passed to p.matcher(). If multiple matches can be found, this method will find the first, and then move to the next match for each subsequent call.

Getting more characters inside matcher group than expected

I'm trying to match the following string against the pattern:
String s = "AAA|VY~1055~ ~~BCN~09/24/2012~";
Matcher m = Pattern.compile("(.*)\\|VY\\~(.*)\\~").matcher(s);
if (m.find())
{
String value = m.group(2);
System.out.print("value = " + value);
}
The output is:
value = 1055~ ~~BCN~09/24/2012
But I want this:
value = 1055
Why is it getting all the characters until the end of string?
I've read something about to consume to the end of string, and I've tried:
Matcher m = Pattern.compile("(.*)\\|VY\\~(.*)\\~(.*)").matcher(s);
Matcher m = Pattern.compile("(.*)\\|VY\\~(.*)\\~.*").matcher(s);
But it doesn't work.
Can anybody help me?
Use the *? (reluctant) quantifier, which is lazy (stops matching as soon as possible).
Matcher m = Pattern.compile("(.*)\\|VY\\~(.*?)\\~").matcher(s);
You want to read about the gready, reluctant and possessive quantifiers (need to scroll down a bit).

rules for use reg exp java

i have pattern:
host=([a-z0-9./:]*)
it's find for me host address. And i have content
host=http//:sdf3452.domain.com/
And my code is:
Matcher m;
Pattern hostP = Pattern.compile("host=([a-z0-9./:]*)");
m=hostP.matcher(content);//string 1
String match = m.group();//string 2
Log.i("host", ""+hostP.matcher(content).find());
if i delete string 1 and 2 i see true in logcat. If left as is I got exception nothing found.
I've tried all kinds of pattern. Through debug looked m variable, finds no match. Please teach me use reg exp!
Before you group() a match, you need to invoke find().
Try it like this:
Pattern hostP = Pattern.compile("host=([a-z0-9./:]*)");
Matcher m = hostP.matcher(content);
if(m.find()) {
String match = m.group();
// ...
}
EDIT
and a little demo that shows what each match-group contains:
Pattern p = Pattern.compile("host=([a-z0-9./:]*)");
Matcher m = p.matcher("host=http://sdf3452.domain.com/");
if (m.find()) {
for(int i = 0; i <= m.groupCount(); i++) {
System.out.printf("m.group(%d) = '%s'\n", i, m.group(i));
}
}
which will print:
m.group(0) = 'host=http://sdf3452.domain.com/'
m.group(1) = 'http://sdf3452.domain.com/'
As you can see, group(0), which is the same as group(), contains what the entire pattern matches.
But realize that a URL can contain much more than what your defined in [a-z0-9./:]*!
String content = "host=http://sdf3452.domain.com/";
Matcher mm;
Pattern hostP = Pattern.compile("host=([a-z0-9./:]*)");
mm=hostP.matcher(content);
String match = "";
if (mm.find()){//use m.find() first
match = mm.group(1);//1 is order number of brackets
}

Categories

Resources