Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/323.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
(!a){0}是什么意思?在Java正则表达式中是什么意思?_Java_Android_Regex_Split - Fatal编程技术网

(!a){0}是什么意思?在Java正则表达式中是什么意思?

(!a){0}是什么意思?在Java正则表达式中是什么意思?,java,android,regex,split,Java,Android,Regex,Split,受此启发,我开始使用一些包含{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 +

受此启发,我开始使用一些包含
{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})");
} 

为什么Android中的正则表达式的行为不同于普通Java?

我研究了oracles Java 1.7的源代码

“{0}”

我发现一些代码在主循环中找到?、*或+时抛出“悬空元字符”。也就是说,不能紧跟在某个文本、组、
或明确检查量词的任何其他地方之后。出于某种原因,
{
不在该列表中。结果是它通过了所有特殊字符检查,并开始解析文本字符串。它遇到的第一个字符是
{
,它告诉解析器是时候停止解析文本字符串并检查量词了

结果是,
“{n}”
将匹配空字符串n次

另一个结果是第二个
“x{m}{n}”
将首先匹配
x
m
次,然后匹配空字符串
n
次,有效地忽略
{n}
,正如@Kobi在上面的评论中提到的那样

对我来说似乎是个bug,但如果他们想保留它以实现向后兼容性,我也不会感到惊讶

“(?!a){0}”

“(?!a)”
只是一个可量化的节点。您可以检查下一个字符是否为“a”10次。但每次都会返回相同的结果,因此这不是很有用。在我们的示例中,它将检查下一个字符是否为“a”0次,这将始终成功

请注意,作为一种优化,当匹配的长度为0(如此处)时,量词从不贪婪。这也防止了
“(?!a)*”
情况下的无限递归


“(?!a)。{0}”和“{0}(?仅供参考,你可以在这里测试java:哈哈,我甚至不知道这个网站:-)@martincarneye还有这个问题-如果你不介意的话,我直接链接到我的答案,因为我认为它是相关的。基本上,java忽略了冗余的
{n}
,这在大多数其他正则表达式中是非法的(如您发布的示例中所示)。这与代码高尔夫无关。这是关于对java正则表达式引擎如何工作的深入理解。Android与java之间有些不同并不奇怪,尤其是像这样的情况,因为Android java是java的重新实现,就像Linux是Unix的重新实现,但无法直接访问源代码一样。Android使用ICU正则表达式,它与Java相似,但在支持的结构方面与Java不同。引擎如何解释量词并不重要。底线是,量词/重复运算符在不量化任何内容的情况下不能存在于状态机中。而且,它们不能被解释为独立状态。
伊森,{不在该列表中
-你是说没有解析有效的范围量词吗?那不是真的。
{5}
在某个地方被解析为重复运算符,否则它是一个文本。没有有效的前导值,就没有有效的量词解释。因此,
x{3}{8}
被解析为嵌套的量词,它没有任何意义。
这也防止了“(?!a)*”情况下的无限递归。
断言上的所有量词都解析为1或0。与非贪婪循环或无限循环无关。这可以用基准测试。
Regex1:(?!a){400000100000000}完成的迭代:每次迭代发现的50/50(x 1000)个匹配:2个运行时间:0.26秒、256.39毫秒、256387微秒正则表达式2:(?!a)+完成的迭代:每次迭代发现的50/50(x 1000)个匹配:2个运行时间:0.25秒、254.53毫秒、254529微秒(?!a){400000100000000}已完成迭代:每次迭代找到50/50(x 1000)个匹配项:2个经过时间:0.25秒、254.34毫秒、254339µs Regex2:(?!a){1}已完成迭代:50/50(x 1000)每次迭代找到的匹配项:2个经过的时间:0.25秒、254.06毫秒、254059微秒
,所以贪婪/非贪婪与此无关。@sln
量词不能在状态机中存在,如果它们不量化任何东西
。正是如此。这就是为什么在主循环中,当没有什么可量化时,代码抛出“挂起元字符。例如,使用regex
“+”
。只有
{
字符漏掉,这似乎是一个错误。当Java解析可以量化的字符时,它将检查
{
,并正常工作。
"":              [, J, u, s, t,  , a,  , t, e, s, t, -, p, h, r, a, s, e, !, !,  , 1, ., 2, ., 3, ., .,  , @,  , {, (, t, ·, e, ·, s, ·, t, ), }]
"{0}":           [, J, u, s, t,  , a,  , t, e, s, t, -, p, h, r, a, s, e, !, !,  , 1, ., 2, ., 3, ., .,  , @,  , {, (, t, ·, e, ·, s, ·, t, ), }]
".{0}":          [, J, u, s, t,  , a,  , t, e, s, t, -, p, h, r, a, s, e, !, !,  , 1, ., 2, ., 3, ., .,  , @,  , {, (, t, ·, e, ·, s, ·, t, ), }]
"([^.]{0})?+":   [, J, u, s, t,  , a,  , t, e, s, t, -, p, h, r, a, s, e, !, !,  , 1, ., 2, ., 3, ., .,  , @,  , {, (, t, ·, e, ·, s, ·, t, ), }]
"(?!a){0}":      [, J, u, s, t,  , a,  , t, e, s, t, -, p, h, r, a, s, e, !, !,  , 1, ., 2, ., 3, ., .,  , @,  , {, (, t, ·, e, ·, s, ·, t, ), }]
"(?!a).{0}":     [, J, u, s, t,  a,  , t, e, s, t, -, p, h, ra, s, e, !, !,  , 1, ., 2, ., 3, ., .,  , @,  , {, (, t, ·, e, ·, s, ·, t, ), }]
"(?!.{0}).{0}":  [Just a test-phrase!! 1.2.3.. @ {(t·e·s·t)}]
".{0}(?<!a)":    [, J, u, s, t,  , a , t, e, s, t, -, p, h, r, as, e, !, !,  , 1, ., 2, ., 3, ., .,  , @,  , {, (, t, ·, e, ·, s, ·, t, ), }]
".{0}(?<!.{0})": [Just a test-phrase!! 1.2.3.. @ {(t·e·s·t)}]
03-20 22:43:31.941: D/AndroidRuntime(2799): Shutting down VM
03-20 22:43:31.950: E/AndroidRuntime(2799): FATAL EXCEPTION: main
03-20 22:43:31.950: E/AndroidRuntime(2799): java.lang.RuntimeException: Unable to start activity ComponentInfo{com.appham.courseraapp1/com.appham.courseraapp1.MainActivity}: java.util.regex.PatternSyntaxException: Syntax error in regexp pattern near index 6:
03-20 22:43:31.950: E/AndroidRuntime(2799): (?!a){0}
03-20 22:43:31.950: E/AndroidRuntime(2799):       ^
03-20 22:43:31.950: E/AndroidRuntime(2799):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2180)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2230)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at android.app.ActivityThread.access$600(ActivityThread.java:141)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1234)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at android.os.Handler.dispatchMessage(Handler.java:99)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at android.os.Looper.loop(Looper.java:137)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at android.app.ActivityThread.main(ActivityThread.java:5041)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at java.lang.reflect.Method.invokeNative(Native Method)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at java.lang.reflect.Method.invoke(Method.java:511)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:793)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:560)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at dalvik.system.NativeStart.main(Native Method)
03-20 22:43:31.950: E/AndroidRuntime(2799): Caused by: java.util.regex.PatternSyntaxException: Syntax error in regexp pattern near index 6:
03-20 22:43:31.950: E/AndroidRuntime(2799): (?!a){0}
03-20 22:43:31.950: E/AndroidRuntime(2799):       ^
03-20 22:43:31.950: E/AndroidRuntime(2799):     at java.util.regex.Pattern.compileImpl(Native Method)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at java.util.regex.Pattern.compile(Pattern.java:407)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at java.util.regex.Pattern.<init>(Pattern.java:390)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at java.util.regex.Pattern.compile(Pattern.java:381)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at java.lang.String.split(String.java:1832)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at java.lang.String.split(String.java:1813)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at com.appham.courseraapp1.MainActivity.onCreate(MainActivity.java:22)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at android.app.Activity.performCreate(Activity.java:5104)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1080)
03-20 22:43:31.950: E/AndroidRuntime(2799):     at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2144)
03-20 22:43:31.950: E/AndroidRuntime(2799):     ... 11 more