受{0}量词实际上有意义的问题的启发我开始使用包含{0}量词的一些正则表达式,并编写了这个基于各种测试正则表达式分割测试短语的小型java程序:
private static final String TEST_STR =
"Just a test-phrase!! 1.2.3.. @ {(t·e·s·t)}";
private static void test(final String pattern) {
System.out.format("%-17s", "\"" + pattern + "\":");
System.out.println(Arrays.toString(TEST_STR.split(pattern)));
}
public static void main(String[] args) {
test("");
test("{0}");
test(".{0}");
test("([^.]{0})?+");
test("(?!a){0}");
test("(?!a).{0}");
test("(?!.{0}).{0}");
test(".{0}(?<!a)");
test(".{0}(?<!.{0})");
}
Run Code Online (Sandbox Code Playgroud)
==>输出:
"": [, J, u, s, t, , a, , t, e, s, t, -, p, h, r, a, s, e, !, !, , 1, ., 2, ., 3, ., …Run Code Online (Sandbox Code Playgroud) 我一直认为Java的regex-API(以及许多其他语言)中的后视断言必须具有明显的长度.因此,STAR和PLUS量词不允许在内部观察.
优秀的在线资源regular-expressions.info似乎证实了(某些)我的假设:
"[...] Java通过允许有限重复更进一步.你仍然不能使用星号或加号,但你可以使用问号和花括号与指定的max参数.Java认识到有限重复的事实可以重写为具有不同但固定长度的字符串的交替.不幸的是,当你在lookbehind中使用交替时,JDK 1.4和1.5有一些错误.这些在JDK 1.6中被修复.[...]"
只要外观中字符范围的总长度小于或等于Integer.MAX_VALUE,就可以使用大括号.所以这些正则表达式是有效的:
"(?<=a{0," +(Integer.MAX_VALUE) + "})B"
"(?<=Ca{0," +(Integer.MAX_VALUE-1) + "})B"
"(?<=CCa{0," +(Integer.MAX_VALUE-2) + "})B"
Run Code Online (Sandbox Code Playgroud)
但这些不是:
"(?<=Ca{0," +(Integer.MAX_VALUE) +"})B"
"(?<=CCa{0," +(Integer.MAX_VALUE-1) +"})B"
Run Code Online (Sandbox Code Playgroud)
但是,我不明白以下几点:
当我运行使用内部的*和+量词测试向后看,一切顺利的话(见输出测试1和测试2).
但是,当我在的开头添加一个字符向后看,从测试1和测试2,它打破(见输出测试3).
让测试3不情愿的贪婪*没有效果,它仍然会中断(参见测试4).
这是测试工具:
public class Main {
private static String testFind(String regex, String input) {
try {
boolean returned = java.util.regex.Pattern.compile(regex).matcher(input).find();
return "testFind : Valid -> …Run Code Online (Sandbox Code Playgroud)