这是我遇到问题的正则表达式:^(?:(\S+?)(?:\s+|\s*$))
。我想匹配的3次出现下面这种模式String
:-execution thisIsTest1 thisIsTest2
。这是获取第一个numberOfArgs
元素并返回List<String>
匹配项填充的方法。问题是:返回的大小List
为1 ....循环始终迭代一次,然后退出...
private final String arguments="-execution thisIsTest1 thisIsTest2";
/**
* Split the first N arguments separated with one or more whitespaces.
* @return the array of size numberOfArgs containing the matched elements.
*/
...
public List<String> fragmentFirstN(int numberOfArgs){
Pattern patt = Pattern.compile("^(?:(\\S+?)(?:\\s+|\\s*$))",Pattern.MULTILINE);
Matcher matc = patt.matcher(arguments);
ArrayList<String> args = new ArrayList<>();
logg.info(arguments);
int i = 0;
while(matc.find()&&i<numberOfArgs){
args.add(matc.group(1));
i++;
}
return args;
}
这是测试类:
private String[] argArr={"-execution",
"thisIsTest1",
"thisIsTest2"
};
...
@Test
public void testFragmentFirstN() throws Exception {
List<String> arr = test.fragmentFirstN(3);
assertNotNull(arr);
System.out.println(arr); ----> prints : [-execution]
System.out.println(test.getArguments()); ----> prints : -execution thisIsTest1 thisIsTest2 <-----
assertEquals(argArr[0],arr.get(0));
--->assertEquals(argArr[1],arr.get(1));<---- IndexOutOfBoundException : Index: 1, Size: 1
assertEquals(argArr[2],arr.get(2));
assertEquals(3,arr.size());
}
我以为Matcher#find()
在循环时会匹配所有可能的char序列。我想念什么?
问题在于正则表达式的边界匹配器与输入字符串(字符)的开头匹配^
。第一次Matcher.find()
在循环中调用,匹配的子字符串为-execution
。这是因为-execution
正则表达式从字符串的开头开始,而正则表达式具有的部分(?:\\s+|\\s*$)
意味着可以-execution
在输入字符串的末尾检测空格字符(在之后的情况)或非空格字符。
第二次迭代将不匹配任何字符串,因为匹配器不再位于输入字符串的开头。因此Matcher.find()
返回false。
您可以尝试删除字符:
Pattern patt = Pattern.compile("(?:(\\S+?)(?:\\s+|\\s*$))",
Pattern.MULTILINE);
编辑:
根据@ajb的注释,简单地删除^
字符将使正则表达式与以空格开头的输入字符串匹配。如果不希望出现这种情况,则可以由匹配器替换为^
,\G
以标记前一次匹配的结束:
Pattern patt = Pattern.compile("\\G(?:(\\S+?)(?:\\s+|\\s*$))",
Pattern.MULTILINE);
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句