简体   繁体   English

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

[英]Replace all odd occurrences of a substring using regex

I have a string ~~40~~ Celsius Temp: 33 Celsius Temp:~~50~~ 我有一个字符串~~40~~ Celsius Temp: 33 Celsius Temp:~~50~~

I want to replace the odd occurrences of substring '~~' ie 1st, 3rd.. with another string '**'. 我想用另一个字符串'**'替换奇数出现的子串'~~',即1st,3rd ..

My output should be **40~~ Celsius Temp: 33 Celsius Temp:**50~~ 我的输出应该是**40~~ Celsius Temp: 33 Celsius Temp:**50~~

How to achieve this with regex in Java? 如何用Java中的正则表达式实现这一目标?

You really need a rudimentary parser to handle this; 你真的需要一个基本的解析器来处理这个问题; regex wasn't designed to count occurrences like this. 正则表达式并非旨在计算这样的事件。 The logic of the code below is simple. 下面代码的逻辑很简单。 Every time we hit a match ~~ we do one of two things. 每次我们打一场比赛~~我们做两件事之一。 If it is an odd occurrence, then we append empty string to the replacement, otherwise we reappend the ~~ which we matched. 如果它是奇怪的,那么我们将空字符串附加到替换,否则我们重新匹配我们匹配的~~

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~~

Demo 演示

我认为对于你的问题陈述,你不需要搜索奇怪的事件,从它显示的例子中,你需要用**(数字)替换~~(数字)并忽略其他格式的~~ ..

Well some have already suggested similar solution but still: 有些人已经建议类似的解决方案,但仍然:

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

Here, ~~(\\d) will search for ~~ followed by digit and replace with ** , to preserve the first digit, using $1 在这里, ~~(\\d)将搜索~~后跟数字并替换为** ,以保留第一个数字,使用$1

You can use replacement of a capturing group, iff the ~~ come strictly in pairs. 您可以使用替换捕获组,如果~~对出现。

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

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

And: 和:

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

Note that it will miss the last odd set of tildes if they are not in matching pairs: 请注意,如果它们不在匹配对中,它将错过最后一组奇数:

replaceOddTildes("An ~~un~~ paired ~~example!").equals("An **un~~ paired ~~example!")`

If that's how you want an unmatched pair handled, of course, then that's fine. 如果你想要一个无与伦比的配对,那当然,那很好。

The pattern in detail: 细节模式:

(?:             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

The replacement for the match is a pair of asterisks followed by the contents of the capturing group. 匹配的替换是一对星号,后面是捕获组的内容。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM