当前位置: 代码迷 >> java >> 使用Java正则表达式删除字符串中的每个其他字符
  详细解决方案

使用Java正则表达式删除字符串中的每个其他字符

热度:22   发布时间:2023-08-02 11:12:16.0

我有这个功课问题,我需要使用正则表达式删除字符串中的每个其他字符。

在一个部分中,我必须删除索引1,3,5处的字符,...我已按如下方式执行此操作:

String s = "1a2b3c4d5";
System.out.println(s.replaceAll("(.).", "$1"));

这打印12345这是我想要的。 基本上我一次匹配两个字符,并替换为第一个字符。 我使用群组捕获来做到这一点。

问题是,我在作业的第二部分遇到问题,我需要删除索引0,2,4处的字符,...

我做了以下事情:

String s = "1a2b3c4d5";
System.out.println(s.replaceAll(".(.)", "$1"));

这打印abcd5 ,但正确的答案必须是abcd 如果输入字符串长度为奇数,则我的正则表达式只是不正确。 如果它是偶数,那么我的正则表达式工作正常。

我想我真的很接近答案,但我不确定如何解决它。

你确实非常接近答案:只需匹配第二个char可选。

String s = "1a2b3c4d5";
System.out.println(s.replaceAll(".(.)?", "$1"));
// prints "abcd"

这是因为:

  • 默认情况下,正则表达式是贪婪的,如果它存在,它将采用第二个字符
    • 当输入为奇数长度时,第二个字符将不会在最后一次替换时出现,但您仍然匹配一个字符(即输入中的最后一个字符)
  • 即使组无法匹配,您仍然可以使用反向引用进行替换
    • 它将替换为空字符串,而不是"null"
    • 这与不同,后者为失败的组返回null

参考


仔细看看第一部分

让我们仔细看看作业的第一部分:

String s = "1a2b3c4d5";
System.out.println(s.replaceAll("(.).", "$1"));
// prints "12345"

在这里你没有必要使用? 对于第二个字符,但它“有效”,因为即使你没有匹配最后一个字符, 你也没必要! 由于问题规范,最后一个字符可以保持不匹配,不替换。

现在假设我们要删除索引1,3,5的字符...,并将字符放在索引0,2,4 ...括号中。

String s = "1a2b3c4d5";
System.out.println(s.replaceAll("(.).", "($1)"));
// prints "(1)(2)(3)(4)5"

A-HA! 现在你遇到了与奇数长度输入完全相同的问题! 您无法将最后一个字符与正则表达式匹配,因为正则表达式需要两个字符,但最后只有一个字符用于奇数长度输入!

解决方案同样是使第二个char匹配可选:

String s = "1a2b3c4d5";
System.out.println(s.replaceAll("(.).?", "($1)"));
// prints "(1)(2)(3)(4)(5)"

如果输入字符串长度是奇数,我的正则表达式只是不正确。 如果它是偶数,那么我的正则表达式工作正常。

将你的表达改为.(.)? - 问号使第二个字符可选,这意味着输入是奇数还是偶数无关紧要

你的正则表达式需要2个字符来匹配,所以最后的字符失败了。

这个正则表达式:

".(.{0,1})"

将第二个char设置为可选,因此它也将与您的最终'5'匹配