don*_*uxx 29 java regex android split
受{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, ., ., , @, , {, (, 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)}]
Run Code Online (Sandbox Code Playgroud)
以下并没有让我感到惊讶:
"",".{0}"并且"([^.]{0})?+"在每个角色之前分开,因为0-quantifier而有意义."(?!.{0}).{0}"并且".{0}(?<!.{0})"不匹配任何东西.对我有意义:0量化令牌的负前瞻/后瞻不匹配.什么都惊讶我:
"{0}"&"(?!a){0}":我实际上在这里期望一个例外,因为前面的标记是不可量化的:因为之前没有{0}任何事情,(?!a){0}而且实际上并不是一个负面的前瞻.两者都在每个char之前匹配,为什么?如果我在javascript验证器中尝试使用正则表达式,我会得到"不可量化的错误",请参阅此处的演示!这个正则表达式在Java和Javascript中的处理方式不同吗?"(?!a).{0}"&".{0}(?<!a)":这里也有一点惊喜:那些在短语的每个字符之前匹配,除了之前/之后a.我的理解是,在(?!a).{0}该(?!a)负先行断言的一部分,这是不可能匹配a字面上看,但我期待未来.{0}.我认为它不适用于0量化的令牌,但看起来我也可以使用Lookahead.==>所以对我来说剩下的谜团是为什么(?!a){0}在我的测试短语中的每个字符之前实际匹配.这不应该是一个无效的模式,并抛出PatternSyntaxException或类似的东西?
更新:
如果我在Android Activity中运行相同的Java代码,结果会有所不同!在那里,正则表达式(?!a){0}确实抛出了PatternSyntaxException,请参阅:
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
Run Code Online (Sandbox Code Playgroud)
为什么Android中的正则表达式与普通Java不同?
小智 13
我做了一些研究oracle java 1.7的来源.
"{0}"
我发现一些代码在主循环中找到?,*或+时抛出"悬空元字符".也就是说,不是在一些文字,组"."或其他明确检查量词的地方之后.出于某种原因,{不在该列表中.结果是它通过对特殊字符的所有检查,并开始解析文字字符串.它遇到的第一个字符是{告诉解析器是时候停止解析文字字符串并检查量词.
结果是"{n}"将匹配空字符串n次.
另一个结果是,第二个"x{m}{n}"将首先匹配x m时间,然后匹配空字符串n时间,有效地忽略{n},如上面的评论中的@Kobi所提到的.
对我来说似乎是一个错误,但如果他们想要保持它的向后兼容性,我不会感到惊讶.
"(?!a){0}"
"(?!a)"只是一个可量化的节点.您可以检查下一个字符是否为'a'10次.它每次都会返回相同的结果,所以它不是很有用.在我们的例子中,它将检查下一个字符是否为'a'0次,这将始终成功.
请注意,当匹配具有0长度(例如此处)时,作为优化,量词从不贪婪.这也可以防止在这种"(?!a)*"情况下无限递归.
"(?!a).{0}" & ".{0}(?<!a)"
如上所述,{0}执行0次检查,总是成功.它实际上忽略了之前发生的任何事情.这意味着"(?!a).{0}"是一样的"(?!a)",里面有预期的结果.
与另一个类似.
Android是不同的
正如@GenericJam所提到的,android是一个不同的实现,在这些边缘情况下可能有不同的特性.我也尝试查看该源代码,但android实际上在那里使用本机代码:)
| 归档时间: |
|
| 查看次数: |
2622 次 |
| 最近记录: |