问题
I've searched many post on this forum and to my surprise, I haven't found anyone with a problem like mine. I have to make a simple calculator for string values from console. Right now,I'm trying to make some regexes to validate the input. My calculator has to accept numbers with spaces between the operators (only + and - is allowed) but not the ones with spaces between numbers, to sum up: 2 + 2 = 4 is correct, but 2 2 + 2 --> this should make an error and inform user on the console that he put space between numbers.
I've come up with this:
static String properExpression = "([0-9]+[+-]?)*[0-9]+$";
static String noInput = "";
static String numbersFollowedBySpace = "[0-9]+[\\s]+[0-9]";
static String numbersWithSpaces = "\\d+[+-]\\d+";
//I've tried also "[\\d\\s+\\d]";
void validateUserInput() {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a calculation.");
input = sc.nextLine();
if(input.matches(properExpression)) {
calculator.calculate();
} else if(input.matches(noInput)) {
System.out.print(0);
} else if(input.matches(numbersFollowedBySpace)) {
input.replaceAll(" ", "");
calculator.calculate();
} else if(input.matches(numbersWithSpaces))
{
System.out.println("Check the numbers.
It seems that there is a space between the digits");
}
else System.out.println("sth else");
Can you give me a hint about the regex I should use?
回答1:
To match a complete expression, like 2+3=24
or 6 - 4 = 2
, a regex like
^\d+\s*[+-]\s*\d+\s*=\s*\d+$
will do. Look at example 1 where you can play with it.
If you want to match longer expressions like 2+3+4+5=14
then you can use:
^\d+\s*([+-]\s*\d+\s*)+=\s*\d+$
Explanation:
^\d+ # first operand
\s* # 0 or more spaces
( # start repeating group
[+-]\s* # the operator (+/-) followed by 0 or more spaces
\d+\s* # 2nd (3rd,4th) operand followed by 0 or more spaces
)+ # end repeating group. Repeat 1 or more times.
=\s*\d+$ # equal sign, followed by 0 or more spaces and result.
Now, you might want to accept an expression like 2=2
as a valid expression. In that case the repeating group could be absent, so change +
into *
:
^\d+\s*([+-]\s*\d+\s*)*=\s*\d+$
Look at example 2 for that one.
回答2:
Try:
^(?:\d+\s*[+-])*\s*\d+$
Demo
Explanation:
- The
^
and$
anchor the regex to match the whole string. - I have added
\s*
to allow whitespace between each number/operator. - I have replaced
[0-9]
with\d
just to simplify it slightly; the two are equivalent.
I'm a little unclear whether you wanted to allow/disallow including = <digits>
at the end, since your question mentions this but your attempted properExpression
expression doesn't attempt it. If this is the case, it should be fairly easy to see how the expression can be modified to support it.
回答3:
Note that I've not attempted to solve any potential issues arising out of anything other than regex issues. Tried as much as possible to keep your logical flow. Although there are other answers which are more efficient but you would've to alter your logical flow a lot.
Please see the below and let me know if you have any questions.
static String properExpression = "\\s*(\\d+\\s*[+-]\\s*)*\\d+\\s*";
static String noInput = "";
static String numbersWithSpaces = ".*\\d[\\s]+\\d.*";
//I've tried also "[\\d\\s+\\d]";
static void validateUserInput() {
Scanner sc = new Scanner(System.in);
System.out.println("Enter a calculation.");
String input = sc.nextLine();
if(input.matches(properExpression)) {
input=input.replaceAll(" ", ""); //You've to assign it back to input.
calculator.calculate(); //Hope you have a way to pass input to calculator object
} else if(input.matches(noInput)) {
System.out.print(0);
} else if(input.matches(numbersWithSpaces)) {
System.out.println("Check the numbers. It seems that there is a space between the digits");
} else
System.out.println("sth else");
Sample working version here
Explanation
The below allows replaceable spaces..
\\s* //Allow any optional leading spaces if any
( //Start number+operator sequence
\\d+ //Number
\\s* //Optional space
[+-] //Operator
\\s* //Optional space after operator
)* //End number+operator sequence(repeated)
\\d+ //Last number in expression
\\s* //Allow any optional space.
Numbers with spaces
.* //Any beginning expression
\\d //Digit
[\\s]+ //Followed by one or more spaces
\\d //Followed by another digit
.* //Rest of the expression
来源:https://stackoverflow.com/questions/46695215/regular-expression-to-match-spaces-between-numbers-and-operators-but-no-spaces-b