使用正则表达式替换所有子字符串的奇数次出现

3

我有一个字符串~~40~~ Celsius Temp: 33 Celsius Temp:~~50~~

我想用另一个字符串 '**' 替换子字符串 '~~' 的奇数次出现,即第1个、第3个等。

我的输出应该是 **40~~ Celsius Temp: 33 Celsius Temp:**50~~

如何在Java中使用正则表达式实现这一功能?


2
这是一个非常奇怪的正则表达式使用方式。强烈建议考虑使用循环来代替完成此任务。(并非所有任务都可以使用正则表达式完成。) - k_ssb
它们总是成对出现吗?如果没有成对出现,它失败或者遗漏最后一个是否可以接受? - David Conrad
4个回答

1
你需要一个基本的解析器来处理这个问题;正则表达式并不适合计算出现次数。下面代码的逻辑很简单。每当我们匹配到 ~~ 时,我们会执行以下两种操作之一。如果它是奇数次出现,则我们将空字符串添加到替换内容中,否则我们重新添加我们匹配到的 ~~
String input = "~~40~~ Celsius Temp: 33 Celsius Temp:~~50~~";
Pattern p = Pattern.compile("~~");
Matcher m = p.matcher(input);
StringBuffer sb = new StringBuffer(input.length());
int i = 0;

while (m.find()) {
    if (i % 2 == 0) {
        m.appendReplacement(sb, "**");
    }
    else {
        m.appendReplacement(sb, m.group(0));
    }
    ++i;
}
m.appendTail(sb);
System.out.println(sb.toString());

**40~~ Celsius Temp: 33 Celsius Temp:**50~~

演示


你应该将它替换为"**"以符合OP的要求,但如果只需要替换成对,那么没有真正的需要计数出现次数。 - David Conrad
@DavidConrad 我不同意你的逻辑,因为谁说我们总是会有~~的_成对_。实际上,我们想要的替换逻辑是迭代,用或不用一对,替换所有奇数次出现的情况,所以... - Tim Biegeleisen
由于 OP 没有明确说明,不清楚 OP 希望如何处理不匹配的对。在我看来,它被视为非法并应该被忽略同样有可能。在 OP 澄清之前,不能再说更多了。 - David Conrad

0

我认为针对你的问题陈述,你无需搜索奇数次出现的情况。从示例中可以看出,你需要将~~(数字)替换为**(数字),并忽略其他格式的~~。


0

虽然有些人已经提出了类似的解决方案,但仍然:

String org = "~~40~~ Celsius Temp: 33 Celsius Temp:~~50~~";
String rep = org.replaceAll("~~(\\d)","**$1");

在这里,~~(\d) 将搜索以 ~~ 开头的数字,并用 ** 替换,以保留第一个数字,使用 $1

-2

如果~~成对出现,你可以使用捕获组的替换。

private final static Pattern pattern = Pattern.compile("(?:~~([^~]+~~))");

public static String replaceOddTildes(String value) {
    return pattern.matcher(test).replaceAll("**$1");
}

并且:

String result = replaceOddTildes("~~40~~ Celsius Temp: 33 Celsius Temp:~~50~~"));

请注意,如果最后一组波浪线没有成对出现,它将被忽略。
replaceOddTildes("An ~~un~~ paired ~~example!").equals("An **un~~ paired ~~example!")`

如果您希望按照这种方式处理不匹配的一对,那当然可以。

模式详细信息:

(?:             a non-capturing group, consisting of
    ~~          a pair of tildes, followed by
    (           a capturing group, consisting of
    [^~]+       one or more characters that is not a tilde, followed by
    ~~          a pair of tildes
    )           end of the capturing group
)               end of the non-capturing group

匹配替换的方式是用一对星号代替捕获组中匹配到的内容。


下投票者是否愿意解释或提出改进建议? - David Conrad

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接