我有这个字符串:
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."
答案 0 :(得分:3)
而不是:
result = line.replaceAll(word, c + word + c);
使用:
result = line.replace(word, c + word + c);
请注意:
你可能正在使用约翰。而不是john和replaceAll api使用正则表达式作为参数。此外,字符定义为单引号而不是双引号,如char c = '-';
答案 1 :(得分:1)
contains
和replaceAll
区分大小写。仅仅因为您会在小写字母的字符串上找到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()))
迭代字符串以找到您的单词,但replace
或replaceAll
仍然需要自己遍历整个字符串以查找需要替换的匹配部分。
如果你想确保无论大小写敏感都能找到令牌,那么正则表达式参数不区分大小写。你可以通过添加(?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 FG
到AB 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