Java正则表达式在Android上的工作方式不同于Java

时间:2015-05-12 08:05:39

标签: java android regex string

我在Android上使用Java正则表达式,我看到了奇怪的差异,如下所示

Java:"COSÌ".replaceAll( "\\W", "" ) ----> "COS"

Android:"COSÌ".replaceAll( "\\W", "" ) ----> "COSÌ"

有人注意到Java和Android String类之间有类似的差异吗?

2 个答案:

答案 0 :(得分:3)

的Android

直接来自the Android documentation,紧跟在简写字符类列表(\d\w\s等)之后:

  

请注意,这些内置类并不仅仅涵盖传统的ASCII范围。例如,\w等同于字符类[\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}]

这也可以解释为什么{1}}不会替换Android版本上运行的相同代码。

虽然短手字符类也与Unicode字符匹配是正确的,但Ì Android文档的样本定义方式已过时。有关详细信息,请参阅附录。

Java SE

相比之下,在Java SE中,默认情况下,\w相当于\w

[a-zA-Z_0-9]仅在指定Pattern.UNICODE_CHARACTER_CLASS标志时匹配Unicode字符。指定标志时:

  • 在Java 7中,\w\w
  • 的定义相同
  • 在Java 8中,[\p{IsAlphabetic}\p{M}\p{Nd}\p{Pc}]已更新为\w

解决方法

直接指定字符类。 ICU正则表达式不支持ASCII字符类:

[\p{IsAlphabetic}\p{M}\p{Nd}\p{Pc}\u200c\u200d]

附录

ICU中[^a-zA-Z0-9_] 的定义

以下是\w随时间演变的方式:

  • 简写字符类\w被定义为\w(如文档中所示),最多为ICU 3.0

  • 来自ICU 3.2(2006年2月24日发布)以及ICU 4.8.1.1[\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}](相当于源代码中的[\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}])用来代替。已更改为revision 16634

  • ICU 49(2012/06/06发布)中,文档中的当前定义使用[\p{Alphabetic}\p{M}\p{Nd}\p{Pc}](相当于源代码中的[\p{Alphabetic}\p{Mark}\p{Decimal_Number}\p{Connector_Punctuation}\u200c\u200d])。已更改为revision 31278

上面的字符串用于构造[\p{Alphabetic}\p{M}\p{Nd}\p{Pc}\u200c\u200d]URX_ISWORD_SET中的regcmp.cpp用于编译正则表达式。

Android使用的ICU版本

即使在android-1.6_r1(甜甜圈),当doBackslashW课程文档贫瘠时,它已经在使用ICU 3.8。 The source code表明它正在使用第二个项目符号点中的定义。

文档可能会回过头来描述最古老版本Android的行为。

参考

如果您想自己浏览Android的源代码:

  • Pattern(Java类库)

    • libcoreandroid-1.6_r1platform/dalvik存储库。 android-2.2.3_r2.1课程位于Pattern
    • libcore/regex/src/main/java/java/util/regex/Pattern.java到现在,platform/libcore存储库。 android-2.3_r1课程位于Pattern
  • /luni/src/main/java/java/util/regex/Pattern.java(C的ICU库)

    • icu4candroid-1.6_r1platform/external/icu4c存储库。可以在android-4.4.4_r2.0.1中找到与正则表达式相关的内容,可以在i18n中找到与Unicode相关的内容。
    • common到现在,platform/external/icu。输入android-5.0.0_r1,然后输入与上述类似的路径。

答案 1 :(得分:1)

查看Android Regular expression syntax documentation

  

请注意,这些内置类不仅涵盖传统类   ASCII范围。例如,\ w等同于字符类   [\p{Ll}\p{Lu}\p{Lt}\p{Lo}\p{Nd}]。有关详细信息,请参阅Unicode TR-18,   并记住每个班级的角色集可以有所不同   Unicode版本之间。如果你真的想只匹配ASCII   字符,指定您想要的显式字符;如果你的意思是0-9   使用[0-9]而不是\d,其中还包括Gurmukhi数字和   等等。

因此,请使用范围确保您只匹配英文字母replaceAll("[^a-zA-Z0-9_]", "")