如何在Java中查找和替换字符串中的所有子字符串?

huangapple go评论69阅读模式
英文:

How find and replace all occurrences of substring in string in Java?

问题

我查看了现有的主题,但是我的任务与论坛上的主题略有不同。
我有这个值:

int j = 37;

而且我有一个字符串:

1) String s1 = "5+2+5+2 --j *2*7+3";
2) String s1 = "5+2+5+2 j-- *2*7+3";
3) String s1 = "5+2+5+2 ++j *2*7+3";
4) String s1 = "5+2+5+2 j++ *2*7+3";

我需要用正则表达式找到 --jj--++jj++,并在字符串中替换这些子字符串为数字值 j

结果字符串应该像这样:

1) 5+2+5+2 36 *2*7+3
2) 5+2+5+2 36 *2*7+3
3) 5+2+5+2 38 *2*7+3
4) 5+2+5+2 38 *2*7+3

使用模式 str.split(search).join(replacement),我可以将字符 j 替换为数字 37

str.split("j").join(37);

然后我得到:

1) String s1 = "5+2+5+2 --37 *2*7+3";
2) String s1 = "5+2+5+2 37-- *2*7+3";
3) String s1 = "5+2+5+2 ++37 *2*7+3";
4) String s1 = "5+2+5+2 37++ *2*7+3";

问题:
但是如何执行这时的算术操作(递增、递减)呢?

英文:

I looked at the existing topics, but my task is slightly different from those on the forum.
I have the value:

int j = 37;

And I have one of the strings:

1) String s1 = "5+2+5+2 --j *2*7+3";
2) String s1 = "5+2+5+2 j-- *2*7+3";
3) String s1 = "5+2+5+2 ++j *2*7+3";
4) String s1 = "5+2+5+2 j++ *2*7+3";

I need with regular expression find --j, j--, ++j, j++ and replace this occurrences of substring in string with number value j;

Result string must be like this:

1) 5+2+5+2 36 *2*7+3
2) 5+2+5+2 36 *2*7+3
3) 5+2+5+2 38 *2*7+3
4) 5+2+5+2 38 *2*7+3

With pattern str.split(search).join(replacement) I can replace the char j with number 37:

str.split("j").join(37);

Then I get:

1) String s1 = "5+2+5+2 --37 *2*7+3";
2) String s1 = "5+2+5+2 37-- *2*7+3";
3) String s1 = "5+2+5+2 ++37 *2*7+3";
4) String s1 = "5+2+5+2 37++ *2*7+3";

Question:
But how to perform the arithmetic operation (increment, decrement) at this time?

答案1

得分: 5

public class Test
{
    public static void main(String[] args)
    {
        int j = 37;
        String s1 = "5+2+5+2 ++j *2*7+3";
        
        // this line swap "j--" or "--j" on j--
        s1 = s1.replaceAll("j--|--j", j-1 + "");
        
        // this line swaps "j++" or "++j" on j++
        s1 = s1.replaceAll("(j\\+\\+)|(\\+\\+j)", j+1 + "");
        
        System.out.println(s1);
    }
}
英文:
public class Test
{
    public static void main(String[] args)
    {
        int j = 37;
        String s1 = "5+2+5+2 ++j *2*7+3";
        
        // this line swap "j--" or "--j" on j--
        s1 = s1.replaceAll("j--|--j", j-1 + "");
        
        // this line swaps "j++" or "++j" on j++
        s1 = s1.replaceAll("(j\\+\\+)|(\\+\\+j)", j+1 + "");
        
        System.out.println(s1);
    }
}

答案2

得分: 3

String.replaceAll 可以如下使用:

int j = 37;
String[] d = {
    "5+2+5+2 --j *2*7+3",
    "5+2+5+2 j-- *2*7+3",
    "5+2+5+2 ++j *2*7+3",
    "5+2+5+2 j++ *2*7+3"
};
        
Arrays.stream(d)
      .map(s -> s.replaceAll("--j|j--", Integer.valueOf(j - 1).toString()))
      .map(s -> s.replaceAll("\\+\\+j|j\\+\\+", Integer.valueOf(j + 1).toString()))
      .forEach(System.out::println);

提供期望输出结果:

5+2+5+2 36 *2*7+3
5+2+5+2 36 *2*7+3
5+2+5+2 38 *2*7+3
5+2+5+2 38 *2*7+3
英文:

String.replaceAll may be used as follows:

int j = 37;
String[] d = {
    "5+2+5+2 --j *2*7+3",
    "5+2+5+2 j-- *2*7+3",
    "5+2+5+2 ++j *2*7+3",
    "5+2+5+2 j++ *2*7+3"
};
        
Arrays.stream(d)
      .map(s -> s.replaceAll("--j|j--", Integer.valueOf(j - 1).toString()))
      .map(s -> s.replaceAll("\\+\\+j|j\\+\\+", Integer.valueOf(j + 1).toString()))
      .forEach(System.out::println);

to provide expected output:

5+2+5+2 36 *2*7+3
5+2+5+2 36 *2*7+3
5+2+5+2 38 *2*7+3
5+2+5+2 38 *2*7+3

答案3

得分: 3

请注意,在问题中,操作不遵循Java的行为,即前缀递增和后缀递增都像前缀递增一样。

要实现这种行为,我们需要两个正则表达式:

  • 一个表达式匹配所有--jj--,将它们替换为j - 1的值:

    [-]{2}j|j[-]{2}

  • 一个表达式匹配所有++jj++,将它们替换为j + 1的值:

    [+]{2}j|j[+]{2}

将它们组合起来,我们可以编写以下方法:

public static String replaceJWith(String s, int valueForJ) {
    s = s.replaceAll("--j|j--", Integer.toString(valueForJ - 1));
    return s.replaceAll("++j|j++", Integer.toString(valueForJ + 1));
}

这个实现假定每次出现j时,都会前缀或后缀地带有++--。此外,由于我们实际上没有改变j的值,因此在单个字符串中使用多个前缀和后缀递增运算符会导致意外的行为。


如果我们想要模仿Java的行为(即区分前缀和后缀递增),我们需要三个不同的正则表达式,因为我们必须用三个不同的值替换j

  • 一个正则表达式用于将j(++|--)替换为j的原始值:

    j(?:[+]{2}|[-]{2})

  • 一个正则表达式用于将++j替换为值j + 1

    [+]{2}j

  • 一个正则表达式用于将--j替换为值j - 1

    [-]{2}j

将它们组合起来,我们可以编写以下Java方法:

public static String replaceJWith(String s, int valueForJ) {
    s = s.replaceAll("j(?:[+]{2}|[-]{2})", Integer.toString(valueForJ));
    s = s.replaceAll("[+]{2}j", Integer.toString(valueForJ + 1));
    return s.replaceAll("[-]{2}j", Integer.toString(valueForJ - 1));
}

这个解决方案与第一个解决方案具有相同的限制。

英文:

Note that in the question, the operations do not follow the Java behaviour, i.e. pre- and postincrement both behave like preincrement.

To implement this behaviour, we need two regular expressions:

  • One expression matching all --j and j-- to replace them with the value of j - 1:

    [-]{2}j|j[-]{2} <kbd>Regex101 demo</kbd>

  • One expression matching all ++j and j++ to replace them with the value of j + 1:

    [+]{2}j|j[+]{2} <kbd>Regex101 demo</kbd>

Putting it together, we can write the following method:

public static String replaceJWith(String s, int valueForJ) {
    s = s.replaceAll(&quot;[-]{2}j|j[-]{2}&quot;, Integer.toString(valueForJ - 1));
    return s.replaceAll(&quot;[+]{2}j|j[+]{2}&quot;, Integer.toString(valueForJ + 1));
}

<kbd>Ideone demo</kbd>

This implementation assumes that each occurrence of j is pre- or suffixed by ++ or --. Also, since we never really change the value of j, using multiple pre-, and postincrement operators in a single String will result in unexpected behaviour.


If we want to mimic the Java behaviour (i.e. distinguish between pre- and postincrement), we need three different regular expressions since we have to replace j with three different values:

Setting it all together, we can write the following Java method:

public static String replaceJWith(String s, int valueForJ) {
    s = s.replaceAll(&quot;j(?:[+]{2}|[-]{2})&quot;, Integer.toString(valueForJ));
    s = s.replaceAll(&quot;[+]{2}j&quot;, Integer.toString(valueForJ + 1));
    return s.replaceAll(&quot;[-]{2}j&quot;, Integer.toString(valueForJ - 1));
}

<kbd>Ideone demo</kbd>

This solution has the same limitations as the first solution.

答案4

得分: 0

你可以使用一系列的if语句来检查字符串是否包含每个模式,使用contains()方法,然后用相应的值替换模式:

if (s1.contains("--j")) {
  s1.replace("--j", String.valueOf(j-1)); //假设在之前你已经声明了int j = 37;
} else if (s1.contains("j--")) {
  //等等。
} [...]
英文:

You can use a series of if statements that check the string for the presence of each of those patterns using contains() and then replace the pattern with the corresponding value:

if (s1.contains(&quot;--j&quot;) {
  s1.replace(&quot;--j&quot;, String.valueOf(j-1)); //assuming you have declared int j = 37; before 
} else if (s1.contains(&quot;j--&quot;)) { 
  //etc.
} [...]

huangapple
  • 本文由 发表于 2020年9月7日 04:22:06
  • 转载请务必保留本文链接:https://go.coder-hub.com/63768567.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定