我有一个带有(?:)格式的非捕获组的java正则表达式,我无法理解为什么它会给出" null"匹配非捕获组。
如果我将下面的正则表达式缩短为" @te(st)(?:aa)?"使用相同的?:非捕获组,它给出我认为的预期行为,仅匹配1组和完全匹配。
请参阅下面的正则表达式:
package com.company;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
final String regex = "@test\\s+([:.\\w\\\\x7f-\\xff]+)(?:[\\t ]+(\\S*))?(?:[\\t ]+(\\S*))?\\s*$";
final String string = " /**\n * @test TestGroup\n */\n";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
}
}
结果:
Full match: @test TestGroup
Group 1: TestGroup
Group 2: null
Group 3: null
&#34; @te(st)(?:aa)的结果?&#34;使用相同的代码:
Full match: @test
Group 1: st
第一个将非捕获组匹配为null的正则表达式是什么?
答案 0 :(得分:3)
这是问题中的正则表达式模式:
"@test\\s+([:.\\w\\\\x7f-\\xff]+)(?:[\\t ]+(\\S*))?(?:[\\t ]+(\\S*))?\\s*$"
此正则表达式模式有三个捕获组:
([:.\\w\\\\x7f-\\xff]+)
(\\S*)
(\\S*)
因此,您的第一个示例未将非捕获组与null
匹配。相反,正如预期的那样,它将最后两个捕获组匹配为null
。
如果我们将示例字符串更改为可匹配模式中所有三个捕获组的内容,我们将看到三个匹配项。例如:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
final String regex = "@test\\s+([:.\\w\\\\x7f-\\xff]+)(?:[\\t ]+(\\S*))?(?:[\\t ]+(\\S*))?\\s*$";
final String string = "foo @test : bar baz\n";
// final String string = " /**\n * @test TestGroup\n */\n";
final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE);
final Matcher matcher = pattern.matcher(string);
while (matcher.find()) {
System.out.println("Full match: " + matcher.group(0));
for (int i = 1; i <= matcher.groupCount(); i++) {
System.out.println("Group " + i + ": " + matcher.group(i));
}
}
}
}
上述代码的输出是:
Full match: @test : bar baz
Group 1: :
Group 2: bar
Group 3: baz
其他语言中的更多示例如下所示,表明此行为在各种实现中大致相同。
import re
regex = re.compile('@test\\s+([:.\\w\\\\x7f-\\xff]+)(?:[\\t ]+(\\S*))?(?:[\\t ]+(\\S*))?\\s*$', re.MULTILINE)
s1 = ' /**\n * @test TestGroup\n */\n'
s2 = 'foo @test : bar baz';
match = re.search(regex, s1)
for i in range(regex.groups + 1):
print('Group {}: {}'.format(i, match.group(i)))
print()
match = re.search(regex, s2)
for i in range(regex.groups + 1):
print('Group {}: {}'.format(i, match.group(i)))
输出结果为:
Group 0: @test TestGroup
Group 1: TestGroup
Group 2: None
Group 3: None
Group 0: @test : bar baz
Group 1: :
Group 2: bar
Group 3: baz
第二次匹配显示非捕获组内的捕获组确实匹配。唯一与Python没什么不同的是,不匹配的组不会出现在第一个示例的输出中。
var regex = new RegExp('@test\\s+([:.\\w\\\\x7f-\\xff]+)(?:[\\t ]+(\\S*))?(?:[\\t ]+(\\S*))?\\s*$', 'm')
var s1 = ' /**\n * @test TestGroup\n */\n'
var s2 = 'foo @test : bar baz';
var i
var result = regex.exec(s1)
for (i = 0; i < result.length; i++) {
console.log('result[' + i + '] :', result[i])
}
console.log()
var result = regex.exec(s2)
for (i = 0; i < result.length; i++) {
console.log('result[' + i + '] :', result[i])
}
输出结果为:
result[0] : @test TestGroup
result[1] : TestGroup
result[2] : undefined
result[3] : undefined
result[0] : @test : bar baz
result[1] : :
result[2] : bar
result[3] : baz
<?php
$regex = "/@test\\s+([:.\\w\\\\x7f-\\xff]+)(?:[\\t ]+(\\S*))?(?:[\\t ]+(\\S*))?\\s*$/m";
$s1 = " /**\n * @test TestGroup\n */\n";
$s2 = "foo @test : bar baz";
preg_match($regex, $s1, $matches);
for ($i = 0; $i < count($matches); $i++) {
echo "Match $i: $matches[$i]\n";
}
echo "\n";
preg_match($regex, $s2, $matches);
for ($i = 0; $i < count($matches); $i++) {
echo "Match $i: $matches[$i]\n";
}
?>
输出结果为:
Match 0: @test TestGroup
Match 1: TestGroup
Match 0: @test : bar baz
Match 1: :
Match 2: bar
Match 3: baz