简体   繁体   中英

Replace all odd occurrences of a substring using regex

I have a string ~~40~~ Celsius Temp: 33 Celsius Temp:~~50~~

I want to replace the odd occurrences of substring '~~' ie 1st, 3rd.. with another string '**'.

My output should be **40~~ Celsius Temp: 33 Celsius Temp:**50~~

How to achieve this with regex in 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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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