Java替换所有替换每两次中的一次

Java替换所有替换每两次中的一次,java,string,replaceall,Java,String,Replaceall,我在一个非常简单的问题上有一种奇怪的行为 我有一个包含大量空字符串的字符串: a;BC无效的无效的无效的无效的无效的无效的无效的无效的无效的空的 我使用此方法删除了以下内容: public String replaceAllNull(String s) { s = s.replaceAll(";null;", ";;"); //if first item = null remove it if(s.startsWith("null;")) { s = s

我在一个非常简单的问题上有一种奇怪的行为

我有一个包含大量空字符串的字符串:

a;BC无效的无效的无效的无效的无效的无效的无效的无效的无效的空的

我使用此方法删除了以下内容:

public String replaceAllNull(String s) {
    s = s.replaceAll(";null;", ";;");

    //if first item = null remove it
    if(s.startsWith("null;")) {
        s = s.substring(4,s.length());
    }

    //if last item = null remove it
    if(s.endsWith(";null")) {
        s = s.substring(0,s.length()-4);
    }
    return s;
}
它工作得很好,直到我的弦变大,我看到这个奇怪的输出

a;BC无效的无效的无效的无效

它只删除了两个事件中的一个


我想我可以理解,在一次替换过程中,程序跳过了一次;然后我的正则表达式无法识别第二个null;无效的但是我不明白为什么会发生这种情况?

您可以通过拆分字符串来使用流

return Stream.of(s.split(";", -1))
             .map(w -> "null".equals(w) ? "" : w)
             .collect(Collectors.joining(";"));

可以通过拆分字符串来使用流

return Stream.of(s.split(";", -1))
             .map(w -> "null".equals(w) ? "" : w)
             .collect(Collectors.joining(";"));
在一次犯罪之后;无效的替换为;;,然后两个分号都已经被处理过了,所以第二个分号;不能被视为下一个替换的开始;无效的发生在传递另一个null以到达下一个分号之前,无法再次匹配该模式

您可以使用一种模式,该模式不尝试匹配分号,但必须检查分号是否存在。您可以在链接页面上使用“查找前向”和“查找后向”。在这里,肯定表示它验证了lookbehind/lookahead的模式存在,但不匹配

在一个实例之后,正向查找的格式为?;无效的替换为;;,然后两个分号都已经被处理过了,所以第二个分号;不能被视为下一个替换的开始;无效的发生在传递另一个null以到达下一个分号之前,无法再次匹配该模式

您可以使用一种模式,该模式不尝试匹配分号,但必须检查分号是否存在。您可以在链接页面上使用“查找前向”和“查找后向”。在这里,肯定表示它验证了lookbehind/lookahead的模式存在,但不匹配


正向查找的格式是?一个非常简单的解决方案,请使用此格式而不是上面的大代码

public String replaceAllNull(String s) {
    return s.replace("null" , "");
}
范例

输出

更新以避免这些包含null的单词,这里有一个替代选项


这是一个非常简单的解决方案,使用它代替上面的大代码

public String replaceAllNull(String s) {
    return s.replace("null" , "");
}
范例

输出

更新以避免这些包含null的单词,这里有一个替代选项


在“;”上拆分,删除空字符串,用“;”重新联接在“;”上拆分,删除空字符串,用“;”重新联接对于被“;”包围的空字符串,这不是有同样的问题吗?过滤器不是比地图更合适吗?@FedericoklezCulloca过滤器会删除元素,以减少数量;会少一些。不知道你说的第一个问题是什么意思。这将删除并用空字符串替换每个空单元格;BC因为map返回的内容将包含空字符串,我不确定OP想要什么:这可能只是我的印象,但我认为期望的结果将是一个空字符串;BC这就是我建议使用过滤器的原因;BC在我的情况下,这是必要的,我测试了这个答案,它与不同的情况下,它的工作@Redracoon您可以通过单击左侧的勾号来接受答案。对于用“;”包围的空字符串,这不会有同样的问题吗?过滤器不是比地图更合适吗?@FedericoklezCulloca过滤器会删除元素,以减少数量;会少一些。不知道你说的第一个问题是什么意思。这将删除并用空字符串替换每个空单元格;BC因为map返回的内容将包含空字符串,我不确定OP想要什么:这可能只是我的印象,但我认为期望的结果将是一个空字符串;BC这就是我建议使用过滤器的原因;BC在我的情况下,这是必要的,我测试了这个答案,它与不同的情况下,它的工作@Redracoon您可以通过单击左侧的勾号接受答案。这也会改变单元格中的空值,但这可能是一个合理的假设。e、 这也会改变一个单元格中的空值,但可能是一个合理的假设。e、 这是我在junits测试中测试过的,它完成了所有的测试用例,谢谢!这是工作,我在我的junits测试中测试了它,它完成了所有的测试用例,谢谢!
Before replacing null a;r;c;e;null;d;f;e;null;s;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;null;s;
After replacing null a;r;c;e;;d;f;e;;s;;;;;;;;;;;;;;;;;s;
public static String replaceAllNull(String s) {
    String[] arr = s.split(";");
    for (int i = 0; i < arr.length; i++) {
        if (arr[i].equalsIgnoreCase("null"))
            arr[i] = "";
    }
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < arr.length; i++) {
        sb.append(arr[i]);
        if (i < arr.length - 1)
            sb.append(";");
    }
    if (s.endsWith(";"))
        sb.append(";");
    return sb.toString();
}