I want to match alphanumeric words separated by the operators, +, -, *, /, <, > and ending with a semicolon. There can be whitespace characters in between e.g. the following strings should return true:
first + second;
first - second;
first * second;
first / second;
first;
first + second < third;
third < second * first;
Run Code Online (Sandbox Code Playgroud)
This is what I have tried:
first + second;
first - second;
first * second;
first / second;
first;
first + second < third;
third < second * first;
Run Code Online (Sandbox Code Playgroud)
What is wrong with that code and how can I solve it?
I got the below error on executing my code:
Exception in thread "main" java.util.regex.PatternSyntaxException: Illegal character range near index 9
((([A-Za-Z]+|[0-9]+) ((\*|\/) ([A-Za-Z]+|[0-9]+))? ((\+|\-) ([A-Za-Z]+|[0-9]+) ((\*|\/) ([A-Za-Z]+|[0-9]+))?)? (\<|\= (([A-Za-Z]+|[0-9]+) ((\*|\/) ([A-Za-eZ]+|[0-9]+))? ((\+|\-) ([A-Za-Z]+|[0-9]+) ((\*|\/) ([A-Za-Z]+|[0-9]+))?)?)|(([A-Za-Z]+|[0-9]+) ((\*|\/) ([A-Za-Z]+|[0
-9]+))? ((\+|\-) ([A-Za-Z]+|[0-9]+) ((\*|\/) ([A-Za-Z]+|[0-9]+))?)?
Run Code Online (Sandbox Code Playgroud)
I suggest you, instead of using unnecessarily complex and error-prone logic, simply use the regex, [A-Za-z0-9]+(?:\s*[\/*+\-<>]\s*[A-Za-z0-9]+\s*)*; which covers all the example strings you have posted in the question.
Explanation of the regex:
[A-Za-z0-9]+: 1+ alphabets or digits(?:: Open non-capturing group
\s*: 0+ whitespace characters[\/*+\-<>]: One of /, *, +, -, <, >\s*: 0+ whitespace characters[A-Za-z0-9]+: 1+ alphabets or digits\s*: 0+ whitespace characters): Close non-capturing group*: Quantifier to make the non-capturing group match 0+ times;: The charcter literal, ;Demo:
import java.util.stream.Stream;
public class Main {
public static void main(String[] args) {
// Test
Stream.of(
"first + second;",
"first * second;",
"first - second;",
"first / second;",
"first;",
"first + second < third;",
"third < second * first;"
).forEach(s -> System.out.println(isExpr(s)));
}
public static boolean isExpr(String line) {
return line.matches("[A-Za-z0-9]+(?:\\s*[\\/*+\\-<>]\\s*[A-Za-z0-9]+\\s*)*;");
}
}
Run Code Online (Sandbox Code Playgroud)
Output:
true
true
true
true
true
true
true
Run Code Online (Sandbox Code Playgroud)
Because of the unnecessarily complex logic that you have implemented, one or more of the parentheses in the final regex have not been closed. In addition to that, I can see at least one part where the parenthesis has not been closed e.g.
String compOp = new String("(\\<|\\="); // '<' or '='
Run Code Online (Sandbox Code Playgroud)
It should be
String compOp = new String("(\\<|\\=)"); // '<' or '='
//----------------------------------^
Run Code Online (Sandbox Code Playgroud)
Apart from this, given below are a couple of more things that you should learn/address:
String factor = "[A-Za-z]+|[0-9]+";
String mulOp = "\\*|\\/"; // '*'' or '/'
String addOp = "\\+|\\-"; // '+' or '-'
String compOp = "\\<|\\="; // '<' or '='
Run Code Online (Sandbox Code Playgroud)
a-Z to a-z.