用Java替换字符串中的字符串

时间:2015-03-01 14:31:06

标签: java arrays regex string

我有这个字符串:

String line = "Hello John; , my name is also John.";

和这个字符串:

String word = "John";
char c = "-";

并希望输出:

"Hello -John-; , my name is also -John-."

这是我到目前为止所做的事情:

public String changeString(String line, String word, char c){

String result = null;

    if(line.toLowerCase().contains(word.toLowerCase())){

        result = line.replaceAll(word, c + word + c);

    }

return result;
}

但是,使用此功能我得到此输出:

 String result = "Hello -John;- , my name is also -John.-";

我该如何解决这个问题?

更新:

如果我有一个数组而不是只有一个单词,我该怎样才能使这个工作?

import java.util.*;
import java.lang.*;
import java.io.*;


class Text
{
    public static void main(String[] args) throws Exception {
        String line = "Hello John; , my name: is also John.";
        String[] words = {"John","name"};
        char c = '-';
        changeString(line, words, c);



 }

 public static void changeString(String line, String[] words, char c) {
    String result = null;

    for(int i = 0; i < words.length; i++){
        if (line.toLowerCase().contains(words[i].toLowerCase())) {
            result = line.replaceAll(words[i], c + words[i] + c);
        }
        else
            result = line;
    }
    System.out.println(result);
    }
}

因为输出不是所需的:

"Hello John; , my -name-: is also John."

2 个答案:

答案 0 :(得分:3)

而不是:

result = line.replaceAll(word, c + word + c);

使用:

result = line.replace(word, c + word + c);

请注意:

你可能正在使用约翰。而不是john和replaceAll api使用正则表达式作为参数。此外,字符定义为单引号而不是双引号,如char c = '-';

答案 1 :(得分:1)

containsreplaceAll区分大小写。仅仅因为您会在小写字母的字符串上找到contains的令牌,并不意味着replaceAll也能找到它。

例如,对于像"Hello wordl"和令牌"hello"

这样的字符串
line.toLowerCase().contains(words[i].toLowerCase())

将返回true,但

line.replaceAll(words[i], c + words[i] + c);

将无效,因为words[i]将为hello,但line将包含Hello

实际上这个条件不会给你什么

if (line.toLowerCase().contains(words[i].toLowerCase()))

迭代字符串以找到您的单词,但replacereplaceAll仍然需要自己遍历整个字符串以查找需要替换的匹配部分。

如果你想确保无论大小写敏感都能找到令牌,那么正则表达式参数不区分大小写。你可以通过添加(?i)标志来实现。但是,如果您想要使用正则表达式,请确保您将逃脱其所有元字符,例如. + * ?。要做到这一点,您只需使用Pattern.quote(regex)即可。

所以你的代码看起来像

line.replaceAll("(?i)"+Pattern.quote(words[i]),c + words[i] + c);

如果您只想匹配整个单词,则需要使用单词边界\b包围正则表达式。

line.replaceAll("(?i)\\b"+Pattern.quote(words[i])+"\\b", c + words[i] + c);

代码中的第二个问题是

result = line.replaceAll(words[i], c + words[i] + c);` 

您正在覆盖result的当前值以及line中替换值的新结果。但是你忘了 line不会改变 。这意味着,如果您替换John并将其存储在result中,则John中仍会有原始line。这意味着下次当您尝试替换name

line.replaceAll(name, ...)

将返回John(无需替换)。

要解决此问题,您只需将替换结果存储在line本身,如

line = line.replaceAll(words[i], c + words[i] + c);

而不是result


所以你的最终代码看起来像这样

public static void changeString(String line, String[] words, char c) {
    for (int i = 0; i < words.length; i++) {
        line = line.replaceAll(words[i], c + words[i] + c);
    }
    System.out.println(line);
}

但是还有一个问题你可能要解决,如果你想用X替换Y而用Y替换X会怎样?我的意思是AB X DE Y FGAB Y DE X FG

如果您在第一次迭代中使用您的方法,您将删除所有X元素并将其替换为Y,这将为您提供

AB X DE Y FG
AB Y DE Y FG

但在第二种方法中,您会将所有Y替换为X

AB Y DE Y FG
AB X DE X FG

最终会为您AB X DE X FG而不是AB Y DE X FG

要解决此类问题,您应该考虑在一个循环中查找所有元素,在其中迭代所有字符并检查它们是否与任何搜索元素相匹配。例如,您可以使用我以前的答案之一解决此类问题:Replace While Pattern is Found