【问题标题】:Regular Expression to match spaces between numbers and operators but no spaces between numbers正则表达式匹配数字和运算符之间的空格,但数字之间没有空格
【发布时间】:2017-10-11 18:30:27
【问题描述】:

我在这个论坛上搜索了很多帖子,令我惊讶的是,我没有找到像我这样的问题的人。 我必须从控制台为字符串值制作一个简单的计算器。现在,我正在尝试制作一些正则表达式来验证输入。 我的计算器必须接受运算符之间有空格的数字(只允许 + 和 - ),但不能接受数字之间有空格的数字,总结一下: 2 + 2 = 4 是正确的,但是 2 2 + 2 --> 这应该会出错并在控制台上通知用户他在数字之间放置了空格。

我想出了这个:

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");

你能给我一个关于我应该使用的正则表达式的提示吗?

【问题讨论】:

  • 您没有找到答案的原因可能是因为正则表达式不是确定字符串是否是有效数学方程式的好工具!当您开始添加其他运算符(例如括号、指数等)时会发生什么?
  • ...但是,如果我们将问题限制为您提到的简单类型的方程式,那么当然可以使用正则表达式来完成。
  • 在下面使用正则表达式 \d*\s\+\s\d*\s
  • 虽然我同意@TomLord,但在使用正则表达式时,我仍然会尝试帮助您解决问题。为什么不使用\d+\s+\d+ 来检测数字之间有空格的方程?
  • 这只是我必须做的一些糟糕的作业,所有其他操作都应该被视为错误,所以这个计算器永远不会有更多的选择。放置括号或指数应该会出错,因为它不在其规范中。我想所有这些限制真的只会让事情变得更糟:)

标签: java regex string calculator


【解决方案1】:

要匹配一个完整的表达式,比如2+3=246 - 4 = 2,像一个正则表达式

^\d+\s*[+-]\s*\d+\s*=\s*\d+$

会的。看看example 1哪里可以玩。

如果你想匹配更长的表达式,比如2+3+4+5=14,那么你可以使用:

^\d+\s*([+-]\s*\d+\s*)+=\s*\d+$

解释:

^\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.

现在,您可能希望接受像 2=2 这样的表达式作为有效表达式。在这种情况下,重复组可能不存在,因此将+ 更改为*

^\d+\s*([+-]\s*\d+\s*)*=\s*\d+$

查看example 2 的那个。

【讨论】:

    【解决方案2】:

    试试:

    ^(?:\d+\s*[+-])*\s*\d+$
    

    Demo

    解释:

    • ^$ 锚定正则表达式以匹配整个字符串
    • 我添加了\s* 以允许每个数字/运算符之间有空格。
    • 我已将[0-9] 替换为\d,只是为了稍微简化一下;两者是等价的。

    我有点不清楚您是否要允许/禁止最后包含 = <digits>,因为您的问题提到了这一点,但您尝试的 properExpression 表达式并未尝试。如果是这种情况,应该很容易看出如何修改表达式以支持它。

    【讨论】:

    • 注意这不会通过2+ 2-3
    • 另外你也不需要^/$,因为输入只是来自Scanner的一行,matches方法试图匹配整行(根据OP)
    • ^(?:\s*\d+\s*[+-])*\s*\d+$ 将匹配 2+ 2-3
    • 我必须确认,答案中的正则表达式匹配 2 + 2 但 2 + 2-3 不匹配。谢谢马克,你的正则表达式效果最好。
    【解决方案3】:

    请注意,除了正则表达式问题之外,我没有尝试解决任何潜在问题。 尽可能地保持你的逻辑流畅。尽管还有其他更有效的答案,但您必须大量更改逻辑流程。

    请参阅以下内容,如果您有任何问题,请告诉我。

    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");
    

    示例工作版本here


    说明

    下面允许替换空格..

    \\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.
    

    带空格的数字

    .*         //Any beginning expression
    \\d        //Digit
    [\\s]+     //Followed by one or more spaces
    \\d        //Followed by another digit
    .*         //Rest of the expression
    

    【讨论】:

    • 谢谢!是的,当然我有一个计算器类计算方程。带有空格的数字的正则表达式也有效,我想我必须有一些时间单独使用正则表达式:D
    猜你喜欢
    • 2017-08-02
    • 1970-01-01
    • 1970-01-01
    • 2023-01-16
    • 2017-12-24
    • 1970-01-01
    • 2021-01-11
    • 2022-11-24
    • 2011-10-19
    相关资源
    最近更新 更多