【问题标题】:Java replaceAll puts "null" inside resultJava replaceAll 将“null”放入结果中
【发布时间】:2019-11-26 10:14:30
【问题描述】:

我有一个正则表达式:

((((first_url)|(second_url)|(third_url))+\.dom\.local)?|.*)[^.]

这应该检查我的 baseURL 是否是本地的。

如果我在正则表达式测试器站点(如正则表达式 101)中运行它,我会得到正确的结果,我的意思是如果我用“$2”替换,如果字符串中没有我的本地 baseURL 之一,我不会得到任何结果。

但在 Java 中我得到:

String t1 = "first_url.dom.local/service/myService".replaceAll(Constants.REGEX_CHECK_GET_URL_LOCAL, "$2").replaceAll("null", "");
String tt1 = "first_url.dom.local/service/myService".replaceAll(Constants.REGEX_CHECK_GET_URL_LOCAL, "$2");
String t2 = "another_url.dom.local/service/myService".replaceAll(Constants.REGEX_CHECK_GET_URL_LOCAL, "$2").replaceAll("null", "");
String tt2 = "another_url.dom.local/service/myService".replaceAll(Constants.REGEX_CHECK_GET_URL_LOCAL, "$2");

地点:

t1 = "first_url.dom.local"
tt1 = "first_url.dom.localnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnullnull"
t2 = ""
tt2 = "nullnullnullnullnullnullnullnullnullnullnullnull"

为什么“replaceAll”将所有这些“null”放在字符串中? 我通过再次替换“空值”来解决,但我个人认为这是解决这个问题的不好方法。 另外,如果我尝试在线“replaceAll”,我会得到没有“null”字符串的正确结果:/

使用“Pattern”和“Matcher”变量不会改变结果。

另一个例子: 我有一个对象属性,它是头像的 url。此属性可以具有用于下载 avar 的 BaseURL,也可以具有不带 BaseURL 的相对 URL。

我的正则表达式是:

((www)\.(.*.)\.((it)|(com)|(org)))?.*.

替换:

$1

所以这应该只提取 BaseURL(如果存在)(就像我在在线模拟器上尝试的那样);相反,如果我有一个没有 BaseURL 的字符串,它会提取“null”字符串而不是空字符串“”。

【问题讨论】:

  • 如果您可以在minimal reproducible example 中显示所有这些内容,那将非常有帮助,以便我们可以复制/粘贴/编译/运行。
  • 仅使用必需的正则表达式进行简单替换 ((((first_url)|(second_url)|(third_url))+\.dom\.local)?) 哪个组永远不会为空。然后进行后视检查是否没有点跟随。
  • 是的,我在 Android 上听说过。它的引擎与 Java 的有点不同。
  • @Z3R0 我的理解是(...)? 的$1 可以给出一个空值,而((...)?) 会在较大的$1 中给出一个空字符串。与替代品相同的原理((...)|...)
  • @JoopEggen 它只适用于没有交替的模式。通常,在 Python 3.4 及更早版本中,常见的解决方法是使用 lambda 表达式(可调用)作为替换参数,其中可以检查组值是否不为空。在这里,可以使用Matcher#appendReplacement

标签: android regex replaceall


【解决方案1】:

我们需要更多详细信息,因为您的错误无法重现。由于此测试完美运行:

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

public class ReplaceRegex {

    @Test
    void checkRegExp() {
        String regex = "((((first_url)|(second_url)|(third_url))+\\.dom\\.local)?|.*)[^.]";
        String t1 = "first_url.dom.local/service/myService".replaceAll(regex, "$2").replaceAll("null", "");
        String tt1 = "first_url.dom.local/service/myService".replaceAll(regex, "$2");
        String t2 = "another_url.dom.local/service/myService".replaceAll(regex, "$2").replaceAll("null", "");
        String tt2 = "another_url.dom.local/service/myService".replaceAll(regex, "$2");

        assertThat(t1).isEqualTo("first_url.dom.local");
        assertThat(t1).isEqualTo(tt1);
        assertThat(t2).isEqualTo("");
        assertThat(t2).isEqualTo(tt2);
    }
}

在 Open JDK12 上以绿色传递。

您确定您导入的常量是正确的吗?

【讨论】:

  • jdk是JDK11
  • 我的代码是否在您的项目中的测试类中运行?
  • 未经测试,我没有使用 jupiter :/ 无论如何,如果我使用调试器运行应用程序时它不起作用,我认为它也不起作用。我认为答案在上面帖子中的 cmets 上:/ 无论如何我在 Android 环境中使用 Java
猜你喜欢
  • 2016-04-02
  • 1970-01-01
  • 2017-03-30
  • 2021-11-07
  • 1970-01-01
  • 1970-01-01
  • 2011-02-11
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多