简体   繁体   English

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

[英]Replacing strings with strings in Java

I have this String: 我有这个字符串:

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

and this String: 和这个字符串:

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

and want this output: 并希望此输出:

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

Here's what i've managed to do so far: 到目前为止,这是我设法做到的:

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;
}

However, with this function i get this output: 但是,使用此功能,我得到以下输出:

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

How can I solve this ? 我该如何解决?

UPDATE: 更新:

if i have an array instead of only one word, how can i make this work ? 如果我只有一个单词而不是一个数组,我该如何工作?

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);
    }
}

Because the output is not the desired: 由于不需要输出:

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

Instead of : 代替 :

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

Use: 采用:

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

Note aside: 撇开笔记:

You might be using john. 您可能正在使用约翰。 instead of john and replaceAll api uses regex as argument. 而不是john和replaceAll api使用正则表达式作为参数。 Also character is defined with single quotes rather than double quotes like char c = '-'; 字符也用单引号而不是双引号定义,例如char c = '-';

contains and replaceAll is case-sensitive. containsreplaceAll区分大小写。 Just because you will find your token with contains on lower-case version of string, doesn't mean that replaceAll will be able to find it too. 仅仅因为您会在字符串的小写版本中找到contains的令牌,并不意味着replaceAll也将能够找到它。

For instance for string like "Hello wordl" and token "hello" 例如,字符串"Hello wordl"和令牌"hello"

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

will return true , but 将返回true ,但是

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

will not work because words[i] will be hello but line will contain Hello . 将不起作用,因为words[i]helloline会包含Hello

Actually this condition gives you nothing 其实这种情况什么也没给你

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

It iterates over string to find your word, but replace or replaceAll still have to iterate over entire string on their own to find matching parts which needs to be replaced. 它遍历字符串以找到您的单词,但是replacereplaceAll仍必须自己遍历整个字符串以找到需要替换的匹配部分。

If you want to make sure that you will be able to find tokens regardless of case sensitivity make regex argument case-insensitive. 如果要确保无论区分大小写,都能找到标记,请使regex参数不区分大小写。 You can do it by adding (?i) flag to it. 您可以通过添加(?i)标志来实现。 But if you will want to use regex also make sure that you will escape all its metacharacters like . 但是,如果您想使用正则表达式,还请确保您将转义它的所有元字符. + * ? + * ? . To do it you can simply use Pattern.quote(regex) . 为此,您可以简单地使用Pattern.quote(regex)

So your code can look like 所以你的代码看起来像

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

If you want to match only entire words you will need to also surround your regex with word-boundary \\b . 如果只想匹配整个单词,则还需要用单词边界\\b包围正则表达式。

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

Second problem in your code is that in 您代码中的第二个问题是

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

you are overriding current value of result with new result of replacing value in line . 您正在用替换line值的新结果覆盖result当前值。 But you forgot that line doesn't change . 但是你忘记了那条line不会改变 It means that if you replace John and store it in result you will still have original John in line . 这意味着,如果要更换John并将其存储在result你也有原来的Johnline This means that next when you will try to replace name 这意味着下次您尝试替换name

line.replaceAll(name, ...)

will return you John (without replacement). 将返回您约翰(无替代)。

To correct this problem you can simply store result of replacement in line itself like 要解决此问题,您可以简单地将替换结果存储line本身中,例如

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

instead of some result . 而不是一些result


So your final code can look like this 所以您的最终代码可能如下所示

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);
}

But there is one other problem you may wan to solve, what if you would like to replace X with Y and Y with X ? 但是,您可能还想解决另一个问题,如果您想用Y替换X并用X替换Y呢? I mean something like AB X DE Y FG into AB Y DE X FG . 我的意思是将AB X DE Y FG转换为AB Y DE X FG

If you use your approach in first iteration you will get rid of all X elements and replace them with Y , which will give you 如果您在第一次迭代中使用该方法,则将摆脱所有X元素,并用Y替换它们,这将为您提供

AB X DE Y FG
AB Y DE Y FG

but in second approach you will replace all Y with X 但是在第二种方法中,您将用X替换所有Y

AB Y DE Y FG
AB X DE X FG

which will finally give you AB X DE X FG instead of AB Y DE X FG . 最终将为您提供AB X DE X FG而不是AB Y DE X FG

To solve this kind of problems you should consider finding all your element in one loop, in which you will iterate over all characters and check if they match any of searched elements . 要解决此类问题,您应该考虑在一个循环中查找所有元素,在其中循环访问所有字符,并检查它们是否与任何搜索到的元素匹配。 You can solve this kind of problem for instance by using approach one of my previous answers: Replace While Pattern is Found 例如,您可以通过使用我以前的答案之一来解决此类问题: 找到模式时进行替换

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

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