很难理解正则表达式的世界。

谁能解释正则表达式产生结果的方式,

如果n为1,结果将为23020,n为2-> 33,n为3-> 2103,4-> 32

    public static void main(String[] args) {
    String s = "some023020 num ber 033 02103 32 meh peh beh 4328";
}

    static String nthNumber(String s, int n) {
      Pattern pattern = Pattern.compile(
        "\\D*(?:\\d+\\D+){" + (n-1) + "}0*(\\d+).*");

      Matcher matcher = pattern.matcher(s);
      matcher.matches();
      return matcher.group(1);
    }

最佳答案

考虑n =1。那么您的模式变为:

\D*(?:\d+\D+){0}0*(\d+).*


首先,您需要了解matcher.group()中的组号。组0包含与完整模式匹配的子字符串。

在您的情况下,这就是整个字符串。为什么?

\D*-匹配零个或多个[^ 0-9],即除0-9以外的所有字符。因此它将匹配前四个字母“ some”。

(?:\d+\D+){0}-匹配[0-9]中的一个或多个和[^ 0-9]中的一个或多个。开头的?:称为non capturing group。这基本上意味着不要将其视为一个整体。 {0}表示应匹配(?:\d+\D+){0}多少次。现在它是0,因此不匹配。

0*-匹配一个或多个0。因此,它与“ some”之后的“ 0”匹配。所以到目前为止,我们已经匹配了some0。

(\d+)-匹配[0-9]中的一个或多个。这匹配“ 23020”。观察\ d +在()内部的情况,并且开始时没有?:。这意味着这将是我们的组1。(这就是为什么n = 1的matcher.group(1)返回23020的原因)。

.*-匹配任何零个或多个字符。因此,它匹配到字符串的末尾。

这就是为什么组0包含完整的字符串的原因。

现在移至组1。

在我们的情况下,组1是(\d+)-包含[0-9]中的一个或多个的子字符串。但这不是。该子字符串之前的字符串部分也应与模式\D*(?:\d+\D+){0}0*匹配。这个非常重要。

因此,让我们快速分析您的字符串。

\D*-与“ some”匹配

(?:\d+\D+){0}-匹配零次出现(由于{0})。所以什么都不匹配。

0*-匹配“ 0”。因此,我们匹配了“ some0”。

(\d+)-匹配23020。

这回答了问题的第一部分:当n = 1时,为什么结果为23020?

在继续之前,请注意空格也是一个由\ D匹配的字符。这听起来微不足道,但经常被忽略。

现在,当n = 2时,您的模式变为:

\D*(?:\d+\D+){1}0*(\d+).*

让我们快速分析一下:

\D*-与“ some”匹配

(?:\d+\D+){1}-这次,我们需要精确匹配一次(?:\d+\D+)的出现。因此,这将是“ 023020 num ber”

0*-匹配0。因此,我们匹配到“ some023020 num ber 0”

(\ d +)-匹配33(由于空格而不匹配33 02103 32)。

因此,当n = 2时,matcher.group(1)返回33。

您可以用相同的方法分析n = 3,4。

希望这可以帮助!迷路时最好做的事情(不一定是正则表达式)是查看官方文档。完整阅读,而不仅仅是在备忘单上刷。这样您可以更好地理解。

10-06 04:34