论坛首页 移动开发技术论坛

android与java正则的不同

浏览 3323 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-05-18   最后修改:2012-05-24
最近玩android写了个计算器(http://freish.iteye.com/blog/1526831)练手,里面用了一些正则,发现android(2.1)的正则实现与Java的并不完全兼容,看代码:

java代码:

       
PrintStream textView = System.out;
		Pattern pattern = null;
        Matcher matcher = null;
        String result = null;
        
        pattern = Pattern.compile("(?<![a-zA-Z])e(?![a-zA-Z])");
        matcher = pattern.matcher("e");
        result = matcher.replaceAll("E");
        textView.append("replace \"(?<![a-zA-Z])e(?![a-zA-Z])\" with \"e\":\t" + result + "\n\n");
        
        try {
	        //测试否定逆序环视中的无限匹配
	        pattern = Pattern.compile("(?<!\\d+)e");
	        matcher = pattern.matcher("e");
	        result = matcher.replaceAll("E");
	        textView.append("replace \"(?<!\\d+)e\" with \"e\":\t" + result + "\n\n");
        } catch (Exception e) {
        	textView.append("replace \"(?<!\\d+)e\" with \"e\" error:\n" + e + "\n\n");
        }
        
        try {
	        //测试肯定逆序环视中的无限匹配
	        pattern = Pattern.compile("(?<=\\d+)e");
	        matcher = pattern.matcher("e");
	        result = matcher.replaceAll("E");
	        textView.append("replace \"(?<=\\d+)e\" with \"e\":\t" + result + "\n\n");
        } catch (Exception e) {
        	textView.append("replace \"(?<=\\d+)e\" with \"e\" error:\n" + e + "\n\n");
        }
        
        
        try {
        	//测试肯定顺序环视中的无限匹配
        	pattern = Pattern.compile("(?=\\d+)e");
        	matcher = pattern.matcher("e");
        	result = matcher.replaceAll("E");
        	textView.append("replace \"(?=\\d+)e\" with \"e\":\t" + result + "\n\n");
        } catch (Exception e) {
        	textView.append("replace \"(?=\\d+)e\" with \"e\" error:\n" + e + "\n\n");
        }
        
        
        try {
        	//测试否定顺序环视中的无限匹配
        	pattern = Pattern.compile("(?!\\d+)e");
        	matcher = pattern.matcher("e");
        	result = matcher.replaceAll("E");
        	textView.append("replace \"(?!\\d+)e\" with \"e\":\t" + result + "\n\n");
        } catch (Exception e) {
        	textView.append("replace \"(?!\\d+)e\" with \"e\" error:\n" + e + "\n\n");
        }
        
        
        textView.flush();




android代码:

       
TextView textView = (TextView)findViewById(R.id.display);
        Pattern pattern = null;
        Matcher matcher = null;
        String result = null;
        
        pattern = Pattern.compile("(?<![a-zA-Z])e(?![a-zA-Z])");
        matcher = pattern.matcher("e");
        result = matcher.replaceAll("E");
        textView.append("replace \"(?<![a-zA-Z])e(?![a-zA-Z])\" with \"e\":\t" + result + "\n\n");
        
        try {
	        //测试否定逆序环视中的无限匹配
	        pattern = Pattern.compile("(?<!\\d+)e");
	        matcher = pattern.matcher("e");
	        result = matcher.replaceAll("E");
	        textView.append("replace \"(?<!\\d+)e\" with \"e\":\t" + result + "\n\n");
        } catch (Exception e) {
        	textView.append("replace \"(?<!\\d+)e\" with \"e\" error:\n" + e + "\n\n");
        }
        
        try {
	        //测试肯定逆序环视中的无限匹配
	        pattern = Pattern.compile("(?<=\\d+)e");
	        matcher = pattern.matcher("e");
	        result = matcher.replaceAll("E");
	        textView.append("replace \"(?<=\\d+)e\" with \"e\":\t" + result + "\n\n");
        } catch (Exception e) {
        	textView.append("replace \"(?<=\\d+)e\" with \"e\" error:\n" + e + "\n\n");
        }
        
        
        try {
        	//测试肯定顺序环视中的无限匹配
        	pattern = Pattern.compile("(?=\\d+)e");
        	matcher = pattern.matcher("e");
        	result = matcher.replaceAll("E");
        	textView.append("replace \"(?=\\d+)e\" with \"e\":\t" + result + "\n\n");
        } catch (Exception e) {
        	textView.append("replace \"(?=\\d+)e\" with \"e\" error:\n" + e + "\n\n");
        }
        
        
        try {
        	//测试否定顺序环视中的无限匹配
        	pattern = Pattern.compile("(?!\\d+)e");
        	matcher = pattern.matcher("e");
        	result = matcher.replaceAll("E");
        	textView.append("replace \"(?!\\d+)e\" with \"e\":\t" + result + "\n\n");
        } catch (Exception e) {
        	textView.append("replace \"(?!\\d+)e\" with \"e\" error:\n" + e + "\n\n");
        }



1、关于第一个例子,原因尚不明确,java可以将e替换为E,而android的替换结果为Ee

2、android的正则实现不支持在逆序环视中的无限匹配,即使用*或+,可以使用区间量词{n,m},其中m的的最大值不能为Integer.MAX_VALUE,区间的最大值在本例中可为10,11就不行了:(?<!\\d{1,10})e
错误堆栈:
Uncaught handler: thread main exiting due to uncaught exception
java.lang.RuntimeException: Unable to start activity ComponentInfo{freish.activity/fr...
(?<!\d+)e
         ^
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2496)
at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512) at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2512)
at android.app.ActivityThread.access$2200(ActivityThread.java:119) at android.app.ActivityThread.access$2200(ActivityThread.java:119)
at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863) at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1863)
at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Handler.dispatchMessage(Handler.java:99)
at android.os.Looper.loop(Looper.java:123) at android.os.Looper.loop(Looper.java:123)
at android.app.ActivityThread.main(ActivityThread.java:4363) at android.app.ActivityThread.main(ActivityThread.java:4363)
at java.lang.reflect.Method.invokeNative(Native Method) at java.lang.reflect.Method.invokeNative(Native Method)
at java.lang.reflect.Method.invoke(Method.java:521) at java.lang.reflect.Method.invoke(Method.java:521)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860) at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:860)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:618)
at dalvik.system.NativeStart.main(Native Method) at dalvik.system.NativeStart.main(Native Method)
Caused by: java.util.regex.PatternSyntaxException: Syntax error U_REGEX_LOOK_BEHIND_L...
(?<!\d+)e
         ^
at com.ibm.icu4jni.regex.NativeRegEx.open(Native Method) at com.ibm.icu4jni.regex.NativeRegEx.open(Native Method)
at java.util.regex.Pattern.compileImpl(Pattern.java:264) at java.util.regex.Pattern.compileImpl(Pattern.java:264)
at java.util.regex.Pattern.<init>(Pattern.java:239) at java.util.regex.Pattern.<init>(Pattern.java:239)
at java.util.regex.Pattern.compile(Pattern.java:179) at java.util.regex.Pattern.compile(Pattern.java:179)
at freish.activity.RegexActivity.onCreate(RegexActivity.java:28) at freish.activity.RegexActivity.onCreate(RegexActivity.java:28)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047) at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1047)
at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459) at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2459)
... 11 more ... 11 more



3、无论是java还是android,顺序环视都可以支持无限匹配

4、在逆序环视中,通过pattern = Pattern.compile("(?=r\\d+)e");如果无限匹配的字符前面还有字符,java也不支持无限匹配,这个好奇怪

5、虽然android的java是通过harmony改造来了,经过在harmony6.0中测试:
System.out.println("e".replaceAll("(?<![a-zA-Z])e(?![a-zA-Z])", "E"));此句的行为正确,不同于第一例中的android的行为
System.out.println("e".replaceAll("(?<!\\d+)e", "E"));//harmony和hotspot都没问题
System.out.println("e".replaceAll("(?<!r\\d+)e", "E"));//harmony没问题,hotspot会报错,J2RE 1.5.0 IBM J9 2.3 Windows XP x86-32也会报错
   发表时间:2012-05-28  
android和java都是什么版本
0 请登录后投票
   发表时间:2012-05-28  
su1216 写道
android和java都是什么版本


android2.1(ApiLevel=7)

hotspot1.5.0_22  1.6.0_26
0 请登录后投票
   发表时间:2012-05-29  
2.1是不是太久远了。。。
你可以试试2.3+
0 请登录后投票
论坛首页 移动开发技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics