having quite some trouble with the following regex.
String fktRegex ="public double " + a+ "2" + b + "(double value) {return value * (.*);}\n";
a and b are Strings that are inserted individually.
The regex works just fine until I want to identify also the number with it. That's the (.*) part...
Any help`? Would be really glad! Thanks.
C.
Judging by your example I think you need to escape few regex meta-characters like { } ( ) * so your regex should probably look more like
"public double " + a + "2" + b + "\\(double value\\) \\{return value \\* (.*);\\}\n";
Demo
// abc2xyz
String a = "abc";
String b = "xyz";
String fktRegex = "public double " + a + "2" + b + "\\(double value\\) \\{return value \\* (.*);\\}\n";
String data = "public double abc2xyz(double value) {return value * 100000;}\n";
Pattern p = Pattern.compile(fktRegex);
Matcher m = p.matcher(data);
if(m.find()){
System.out.println(m.group(1));
}else{
System.out.println("no match found");
}
Related
I'm trying to make a regex to allow only a case of a number then "," and another number or same case seperated by ";" like
57,1000
57,1000;6393,1000
So far i made this: Pattern.compile("\\b[0-9;,]{1,5}?\\d+;([0-9]{1,5},?)+").matcher("57,1000").find();
which work if case is 57,1000;6393,1000 but it also allow letters and don't work when case 57,1000
try Regex "(\d+,\d+(;\d+,\d+)?)"
#Test
void regex() {
Pattern p = Pattern.compile("(\\d+,\\d+)(;\\d+,\\d+)?");
Assertions.assertTrue(p.matcher("57,1000").matches());
Assertions.assertTrue(p.matcher("57,1000;6393,1000").matches());
}
How about like this. Just look for two numbers separated by a comma and capture them.
String[] data = {"57,1000",
"57,1000;6393,1000"};
Pattern p = Pattern.compile("(\\d+),(\\d+)");
for (String str : data) {
System.out.println("For String : " + str);
Matcher m = p.matcher(str);
while (m.find()) {
System.out.println(m.group(1) + " " + m.group(2));
}
System.out.println();
}
prints
For String : 57,1000
57 1000
For String : 57,1000;6393,1000
57 1000
6393 1000
If you just want to match those, you can do the following: It matches a single instance of the string followed by an optional one preceded by a semi-colon.
String regex = "(\\d+,\\d+)(;(\\d+,\\d+))?";
for (String str : data) {
System.out.println("Testing String " + str + " : " +str.matches(regex));
}
prints
Testing String 57,1000 : true
Testing String 57,1000;6393,1000 : true
I have a string which looks like : String s = "date1, calculatedDate(currentDate, 35), false";.
I need to extract all param of verify function. So the expected result should be :
elem[0] = date1
elem[1] = calculatedDate(currentDate, 35)
elem[2] = false
If I use split function on , char but I got this result :
elem[0] = date1
elem[1] = calculatedDate(currentDate
elem[2] = 35)
elem[3] = false
Moreover, the method have to be generic, because some functions have 2 or 7 parameters...
Did you have any solution to help me on that?
You could use StringTokenizer to parse your arguments inside the parentheses:
final static String DELIMITER = ",";
final static String PARENTHESES_START = "(";
final static String PARENTHESES_END = ")";
public static List<String> parseArguments(String text) {
List<String> arguments = new ArrayList<>();
StringBuilder argParsed = new StringBuilder();
StringTokenizer st = new StringTokenizer(text, DELIMITER);
while (st.hasMoreElements()) {
// default: add next token
String token = st.nextToken();
System.out.println("Token: " + token);
argParsed.append(token);
// if token contains '(' we have
// an expression or nested call as argument
if (token.contains(PARENTHESES_START)) {
System.out.println("Nested expression with ( starting: " + token);
// reconstruct to string-builder until ')'
while(st.hasMoreElements() && !token.contains(PARENTHESES_END)) {
// add eliminated/tokenized delimiter
argParsed.append(DELIMITER);
// default: add next token
token=st.nextToken();
System.out.println("Token inside nested expression: " + token);
argParsed.append(token);
}
System.out.println("Nested expression with ) ending: " + token);
}
// add complete argument and start fresh
arguments.add(argParsed.toString());
argParsed.setLength(0);
}
return arguments;
}
It can parse even following input: date1, calculatedDate(currentDate, 35), false, (a+b), x.toString()
Sucessfully found all 5 arguments, including complex ones:
(nested) function-calls like calculatedDate(currentDate, 35)
expressions like (a+b)
method-calls on objects like x.toString()
Run this demo on IDEone.
Read more and extend
There might be more complex texts or grammars to handle (in the future).
Then, if neither regex-capturing, nor string-splitting, nor tokenizing can solve, consider using or generating a PEG- or CFG-parser. See the discussion about Regular Expression Vs. String Parsing.
Try this:
String s = "verify(date1, calculatedDate(currentDate, 35), false)";
Pattern p = Pattern.compile("(?<=verify\\()(\\w+)(,\\s)(.*)(,\\s)((?<=,\\s)\\w+)(?=\\))");
Matcher m = p.matcher(s);
while(m.find()) {
System.out.println(m.group(1) + "\n" + m.group(3) + "\n" + m.group(5));
}
Update for s = "date1, calculatedDate(currentDate, 35), false":
String s = "date1, calculatedDate(currentDate, 35), false";
Pattern p = Pattern.compile("(\\w+)(,\\s)(.*)(,\\s)((?<=,\\s)\\w+)");
Matcher m = p.matcher(s);
while(m.find()) {
System.out.println(m.group(1) + "\n" + m.group(3) + "\n" + m.group(5));
}
Output:
date1
calculatedDate(currentDate, 35)
false
About regex:
(\\w+) one or more(+) word characters
(,\\s) , part
(.*) matches any character, here just the part between two ,
(,\\s) , part
((?<=,\\s)\\w+) ?<= is a positive look behind, helps to catch , false part but does not include ,
If I have string variable :
String word = "wordA";
and I have another string variable :
String fullText= "wordA,A A|wordB,B B|wordC,C C|wordD,D D";
so is it possible to get the value after the comma and ends with | ?
Example
If word equals "wordA" then I get only "A A" because in fullText right after wordA and comma is 'A A' and ends with |
and if word equals "wordD" then varible result is "D D" based on the variable fullText.
So how to get this variable result in Java ?
You can use a simple regular expression. Like this:
String text = fullText.replaceAll(".*" + word + ",([^\\|]+).*", "$1");
Alternatively:
Matcher matcher = Pattern.compile(word + ",([^\\|]+)").matcher(fullText);
matcher.find();
matcher.group(1); // "A A" for word = wordA
If you are using Java8 you can use stream like so :
String result = Arrays.stream(fullText.split("\\|")) // split with |
.filter(s -> s.startsWith(word + ",")) // filter by start with word + ','
.findFirst() // find first or any
.map(a -> a.substring(word.length() + 1)) // get every thing after work + ','
.orElse(null); // or else null or any default value
How about this:
public static String search(String fullText, String key) {
Pattern re = Pattern.compile("(?:^|\\|)" + key + ",([^|]*)(?:$|\\|)");
Matcher matcher = re.matcher(fullText);
if (matcher.find()) {
return matcher.group(1);
}
return null;
}
Example:
String fullText= "wordA,A A|wordB,B B|wordC,C C|wordD,D D";
System.out.println(search(fullText, "wordA"));
System.out.println(search(fullText, "wordB"));
System.out.println(search(fullText, "wordC"));
System.out.println(search(fullText, "wordD"));
Output:
A A
B B
C C
D D
UPDATE: To avoid recompiling the regex at each search:
private static final Pattern RE = Pattern.compile("(?:^|\\|)([^,]*),([^|]*)(?:$|(?=\\|))");
public static String search(String fullText, String key) {
Matcher matcher = RE.matcher(fullText);
while (matcher.find()) {
if (matcher.group(1).equals(key)) {
return matcher.group(2);
}
}
return null;
}
I need to split below string using below regex. but it splits data which comes under brackets.
Input
T(i-1).XX_1 + XY_8 + T(i-1).YY_2 * ZY_14
Expected Output
T(i-1).XX_1 , XY_8 , T(i-1).YY_2 , ZY_14
It should not split data which comes under "(" and ")";
I tried with below code but split data which comes under "(" and ")"
String[] result = expr.split("[+*/]");
any pointer to fix this.
I am new to this regex.
Input
(T(i-1).XX_1 + XY_8) + T(i-1).YY_2 * (ZY_14 + ZY_14)
Output
T(i-1).XX_1 , XY_8 , T(i-1).YY_2 , ZY_14 , ZY_14
if it is T(i-1) need to ignore.
For below expression its not working
XY_98 + XY_99 +XY_100
String lineExprVal = lineExpr.replaceAll("\\s+","");
String[] result = lineExprVal.split("[+*/-] (?!(^))");
You can split every thing outside your parentheses like this :
String str = "T(i-1).XX_1 + XY_8 + T(i-1).YY_2 * ZY_14";
String result[] = str.split("[+*/-] (?!(^))");
//---------------------------^----^^--List of your delimiters
System.out.println(Arrays.toString(result));
This will print :
[T(i-1).XX_1 , XY_8 , T(i-1).YY_2 , ZY_14]
The idea is simple you have to split with your delimiters that not inside your parenthesis.
You can check this here ideone and you can check your regex here Regex demo
EDIT
In your second case you have to use this regex :
String str = "(T(i - 1).XX_1 + XY_8)+ (i - 1).YY_2*(ZY_14 + ZY_14)";
String result[] = str.split("[+*+\\/-](?![^()]*(?:\\([^()]*\\))?\\))");
System.out.println(Arrays.toString(result));
This will give you :
[(T(i-1).XX_1+XY_8), T(i-1).YY_2, (ZY_14+ZY_14)]
^----Group1------^ ^--Groupe2-^ ^--Groupe3-^
You can find the Regex Demo, i inspirit this solution from this post here Regex to match only comma's but not inside multiple parentheses .
Hope this can help you.
Split in your second mathematical expression is really hard if it is not possible, so instead you have to use pattern, it is more helpful, so for your expression, you need this regex :
(\w+\([\w-*+\/]+\).\w+)|((?:(\w+\(.*?\))))|(\w+)
Here is a Demo regex you will understand more.
To get the result you need to loop throw your result :
public static void main(String[] args) {
String input = "(T(i-1).XX_1 + XY_8) + X + T(i-1).YY_2 * (ZY_14 + ZY_14) + T(i-1)";
Pattern pattern = Pattern.compile("(\\w+\\([\\w-*+\\/]+\\).\\w+)|((?:(\\w+\\(.*?\\))))|(\\w+)");
Matcher matcher = pattern.matcher(input);
List<String> reslt = new ArrayList<>();
while (matcher.find()) {//loop throw your matcher
if (matcher.group(1) != null) {
reslt.add(matcher.group(1));
}
//In your case you have to avoid this two groups
// if (matcher.group(2) != null) {
// reslt.add(matcher.group(2));
// }
// if (matcher.group(3) != null) {
// reslt.add(matcher.group(3));
// }
if (matcher.group(4) != null) {
reslt.add(matcher.group(4));
}
}
reslt.forEach(System.out::println);
}
This will gives you :
T(i-1).XX_1
XY_8
X
T(i-1).YY_2
ZY_14
ZY_14
I have a String like below
String phone = (123) 456-7890
Now I would like my program to verify if that my input is the same pattern as string 'phone'
I did the following
if(phone.contains("([0-9][0-9][0-9]) [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]")) {
//display pass
}
else {
//display fail
}
It didn't work. I tried with other combinations too. nothing worked.
Question :
1. How can I achieve this without using 'Pattern' like above?
2. How to do this with pattern. I tried with pattern as below
Pattern pattern = Pattern.compile("(\d+)");
Matcher match = pattern.matcher(phone);
if (match.find()) {
//Displaypass
}
String#matches checks if a string matches a pattern:
if (phone.matches("\\(\\d{3}\\) \\d{3}-\\d{4}")) {
//Displaypass
}
The pattern is a regular expression. Therefor I had to escape the round brackets, as they have a special meaning in regex (they denote capturing groups).
contains() only checks if a string contains the substring passed to it.
I'm not going to dive too deeply into regex syntax, but there definitely is something off with your regex.
"([0-9][0-9][0-9]) [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]"
it containes ( and ) and those have special meaning. Escape them
"\([0-9][0-9][0-9]\) [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]"
and you'll also have to escape your \ for the final
"\\([0-9][0-9][0-9]\\) [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]"
You can write like:
Pattern pattern = Pattern.compile("\\(\\d{3}\\) \\d{3}-\\d{4}");
Matcher matcher = pattern.matcher(sPhoneNumber);
if (matcher.matches()) {
System.out.println("Phone Number Valid");
}
For more information you can visit this article.
It appears that your problem is that you didn't escape the parentheses, so your Regex is failing. Try this:
\([0-9][0-9][0-9]\) [0-9][0-9][0-9]-[0-9][0-9][0-9][0-9]
This works
String PHONE_REGEX = "[(]\\b[0-9]{3}\\b[)][ ]\\b[0-9]{3}\\b[-]\\b[0-9]{4}\\b";
String phone1 = "(1234) 891-6762";
Boolean b = phone1.matches(PHONE_REGEX);
System.out.println("is e-mail: " + phone1 + " :Valid = " + b);
String phone2 = "(143) 456-7890";
b = phone2.matches(PHONE_REGEX);
System.out.println("is e-mail: " + phone2 + " :Valid = " + b);
Output:
is phone: (1234) 891-6762 :Valid = false
is phone: (143) 456-7890 :Valid = true