java - 正则表达式在 Android 中不起作用,但在 Java 中运行良好

标签 java android regex

我有以下代码:

String compact =  Pattern.compile(" *(\\{) *| *(\\}) *").matcher(" { { } } ")
                     .replaceAll("$1$2");

在 Java 中,compact 包含 {{}} - 这是我想要的 - 但在 Android 上,我得到的是 {null{nullnull}null} 这让我抓狂。难道我做错了什么?

下一行在 Android 上产生相同的结果:

String compact =  " { { } } ".replaceAll(" *(\\{) *| *(\\}) *", "$1$2")

这是一个 online Java version对于任何想玩它的人。

如果有帮助,我会在 Mac 上的 Android Studio 中使用 jdk1.7.0_79 针对 Android SDK 23 进行编译。

更新:使用 "\\s*(\\{)\\s*|\\s*(\\})\\s*" 有同样的影响。

最佳答案

我无法告诉您为什么它在 Java 中的行为如此,但我可以告诉您为什么它在 Android 中的行为如此。不过,我可以提供一些有关 Java 的线索。

当您命令 Matcher#replaceAll(String) 时,该类会检查是否有 find(),如果有,它会替换原来的内容在输入中与您提供的替换 String 匹配。

到目前为止一切顺利。

然而,当替换实际上是一个组的表示时,则采用另一条路线。该类尝试找到与该组对应的内容(参见 Matcher#appendEvaluated(StringBuffer, String))并将其append(String) 到内部 StringBuffer

它通过显式调用方法 group(int) 来做到这一点。此方法在 Java 和 Android 中的行为是,如果匹配时没有与给定组相对应的对象,它将返回 null注意:当根本没有匹配项时抛出异常,而不仅仅是当它找不到与组对应的匹配项时抛出异常。例如没有 find()group(int)

最后,当您附加一个 null 对象时,StringBuffer 输出“null”String(字面意思是“null”一词)。因此,对于您要求的每个不存在的组,当有匹配项时,它会在其后附加“null”一词。

replaceAll 的情况下,Java 中使用的算法非常不同并且具有不同的输出。

如果不进行过多测试或修复低效问题(抱歉,仅在 12 月凌晨 3 点浏览 SO 并不能帮助我理清思路),我认为您可以在 Android 中实现与使用您所获得的结果相同的结果在 Java 中使用,通过这样做而不是 replaceAll:

String input = " { { } } ";
Matcher matcher = Pattern.compile(" *(\\{) *| *(\\}) *").matcher(input);
while (matcher.find()) {
    String a = matcher.group(1); // $1
    String b = matcher.group(2); // $2
    String replacement = null;
    if (a != null && b != null) {
        replacement = a + b;
    } else if (a != null) {
        replacement = a;
    } else if (b != null) {
        replacement = b;
    }
    if (replacement != null) {
        input = input.replace(matcher.group(), replacement);
    }
}

如果没有,请告诉我。我只做了一些粗略的测试(毕竟是凌晨 3 点)。

关于java - 正则表达式在 Android 中不起作用,但在 Java 中运行良好,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34235426/

相关文章:

android - 为什么 volley 的响应字符串使用的编码与响应 header 中的编码不同?

android - Expo:React Native 中 VideoPlayer 上的自定义按钮

python - 删除 - 列中每一行中的字符,但仅当它们位于数字之后时

jQuery:使用 .replace() 替换元素内的文本

c# - RegularExpression 属性 - 传入类的属性字段

java - Robolectric 3.0 返回空指针

java - java对象转json

java - 在 WindowBuilder for Eclipse 中隐藏工具栏

java - Android 的 ORMLite 不会使用 foreignAutoRefresh 自动刷新外部对象

android - 当 BottomSheet 在 BottomNavigationView 后面时,Google map 应用程序如何让您拖动它?