很难理解正则表达式的世界。
谁能解释正则表达式产生结果的方式,
如果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。
希望这可以帮助!迷路时最好做的事情(不一定是正则表达式)是查看官方文档。完整阅读,而不仅仅是在备忘单上刷。这样您可以更好地理解。