正则表达式:将所有内容与可选捕获组匹配

时间:2016-04-24 20:27:13

标签: java regex

我有以下正则表达式:

(.*)(?:([\+\-\*\/])(-?\d+(?:\.\d+)?))

意图是以形式(左表达式)(运算符)(右操作数)捕获数学表达式,例如, 1+2+3将被捕获为(1+2)(+)(3)。它还将处理单个操作数,例如1+2将被捕获为(1)(+)(2)。

我遇到的问题是这个正则表达式在没有运算符的单个操作数上不匹配,例如5应该在第一个捕获组中匹配,在第二个和第三个(5)()()中没有任何内容。如果我将最后一部分作为可选项:

(.*)(?:([\+\-\*\/])(-?\d+(?:\.\d+)?))?

然后初始组将始终捕获整个表达式。有什么方法可以让第二部分成为可选的,但是它优先于第一组的贪婪匹配吗?

1 个答案:

答案 0 :(得分:1)

描述

这个正则表达式将:

  • 捕获数学表达式直到最后一次操作
  • 捕获最后一次操作
  • 捕获数学表达式中的最后一个数字
  • 假设每个数字可能带有加号或减号,表示该数字为正数或负数
  • 假设每个数字可能都是非整数
  • 假设数学表达式可以包含任意数量的操作,例如:--- - hosts: webservers remote_user: root tasks: - copy: src=/home/bu/Bilal/site dest=/tmp owner=root group=root mode=777 1+21+2+31+2+3+4
  • 验证字符串是数学表达式。这里没有考虑一些边缘情况,例如使用括号或其他复杂的数学符号。

原始正则表达式

注意这是Java,你需要在这个正则表达式中转义反斜杠。要转义它们,只需将所有1+2+3+4...替换为\

\\

解释

Regular expression visualization

<强>概述

在这个表达式中,我首先验证字符串仅由操作^(?=(?:[-+*/^]?[-+]?\d+(?:[.]\d+)?)*$)([-+]?[0-9.]+$|[-+]?[0-9.]+(?:[-+*/^][-+]?[0-9.]+)*(?=[-+*/^]))(?:([-+*/^])([-+]?[0-9.]+))?$,可选符号-+/*^以及整数或非整数组成。由于已经验证,表达式的其余部分可以简单地将数字称为-+,从而提高了可读性。

捕获论坛

0获取整个字符串 1获取整个字符串,但不包括最后一个操作,如果没有操作,则组1将包含整个字符串 2获取最后一个操作(如果存在) 3获取上一次操作后的数字和符号

[0-9.]+

实施例

示例文字

NODE                     EXPLANATION
----------------------------------------------------------------------
  ^                        the beginning of the string
----------------------------------------------------------------------
  (?=                      look ahead to see if there is:
----------------------------------------------------------------------
    (?:                      group, but do not capture (0 or more
                             times (matching the most amount
                             possible)):
----------------------------------------------------------------------
      [-+*/^]?                 any character of: '-', '+', '*', '/',
                               '^' (optional (matching the most
                               amount possible))
----------------------------------------------------------------------
      [-+]?                    any character of: '-', '+' (optional
                               (matching the most amount possible))
----------------------------------------------------------------------
      \d+                      digits (0-9) (1 or more times
                               (matching the most amount possible))
----------------------------------------------------------------------
      (?:                      group, but do not capture (optional
                               (matching the most amount possible)):
----------------------------------------------------------------------
        [.]                      any character of: '.'
----------------------------------------------------------------------
        \d+                      digits (0-9) (1 or more times
                                 (matching the most amount possible))
----------------------------------------------------------------------
      )?                       end of grouping
----------------------------------------------------------------------
    )*                       end of grouping
----------------------------------------------------------------------
    $                        before an optional \n, and the end of
                             the string
----------------------------------------------------------------------
  )                        end of look-ahead
----------------------------------------------------------------------
  (                        group and capture to \1:
----------------------------------------------------------------------
    [-+]?                    any character of: '-', '+' (optional
                             (matching the most amount possible))
----------------------------------------------------------------------
    [0-9.]+                  any character of: '0' to '9', '.' (1 or
                             more times (matching the most amount
                             possible))
----------------------------------------------------------------------
    $                        before an optional \n, and the end of
                             the string
----------------------------------------------------------------------
   |                        OR
----------------------------------------------------------------------
    [-+]?                    any character of: '-', '+' (optional
                             (matching the most amount possible))
----------------------------------------------------------------------
    [0-9.]+                  any character of: '0' to '9', '.' (1 or
                             more times (matching the most amount
                             possible))
----------------------------------------------------------------------
    (?:                      group, but do not capture (0 or more
                             times (matching the most amount
                             possible)):
----------------------------------------------------------------------
      [-+*/^]                  any character of: '-', '+', '*', '/',
                               '^'
----------------------------------------------------------------------
      [-+]?                    any character of: '-', '+' (optional
                               (matching the most amount possible))
----------------------------------------------------------------------
      [0-9.]+                  any character of: '0' to '9', '.' (1
                               or more times (matching the most
                               amount possible))
----------------------------------------------------------------------
    )*                       end of grouping
----------------------------------------------------------------------
    (?=                      look ahead to see if there is:
----------------------------------------------------------------------
      [-+*/^]                  any character of: '-', '+', '*', '/',
                               '^'
----------------------------------------------------------------------
    )                        end of look-ahead
----------------------------------------------------------------------
  )                        end of \1
----------------------------------------------------------------------
  (?:                      group, but do not capture (optional
                           (matching the most amount possible)):
----------------------------------------------------------------------
    (                        group and capture to \2:
----------------------------------------------------------------------
      [-+*/^]                  any character of: '-', '+', '*', '/',
                               '^'
----------------------------------------------------------------------
    )                        end of \2
----------------------------------------------------------------------
    (                        group and capture to \3:
----------------------------------------------------------------------
      [-+]?                    any character of: '-', '+' (optional
                               (matching the most amount possible))
----------------------------------------------------------------------
      [0-9.]+                  any character of: '0' to '9', '.' (1
                               or more times (matching the most
                               amount possible))
----------------------------------------------------------------------
    )                        end of \3
----------------------------------------------------------------------
  )?                       end of grouping
----------------------------------------------------------------------
  $                        before an optional \n, and the end of the
                           string
----------------------------------------------------------------------

样本捕获组

1+2+-3

在线演示:http://fiddle.re/b2w5wa

示例文字

[0] = 1+2+-3
[1] = 1+2
[2] = +
[3] = -3

样本捕获组

-3

在线演示:http://fiddle.re/07kqra

示例Java代码

[0] = -3
[1] = -3
[2] = 
[3] =