我有以下问题说明
使用
+符号替换字符串中的所有字符,但方法中给定字符串的实例除外
所以例如,如果给出的字符串是,abc123efg并且他们希望我替换除了每个实例之外的每个字符,123那么它将成为+++123+++.
我认为正则表达式可能是最好的,我想出了这个.
str.replaceAll("[^str]","+")
Run Code Online (Sandbox Code Playgroud)
其中str是一个变量,但它不允许我使用该方法而不将其放在引号中.如果我只想替换变量字符串str我该怎么做?我用字符串手动输入它运行它,它在方法上工作,但我可以输入一个变量吗?
截至目前我相信它正在寻找字符串"str"而不是变量字符串.
这是除了两个以外的很多情况的输出权:(
开放测试用例列表:
plusOut("12xy34", "xy") ? "++xy++"
plusOut("12xy34", "1") ? "1+++++"
plusOut("12xy34xyabcxy", "xy") ? "++xy++xy+++xy"
plusOut("abXYabcXYZ", "ab") ? "ab++ab++++"
plusOut("abXYabcXYZ", "abc") ? "++++abc+++"
plusOut("abXYabcXYZ", "XY") ? "++XY+++XY+"
plusOut("abXYxyzXYZ", "XYZ") ? "+++++++XYZ"
plusOut("--++ab", "++") ? "++++++"
plusOut("aaxxxxbb", "xx") ? "++xxxx++"
plusOut("123123", "3") ? "++3++3"
Run Code Online (Sandbox Code Playgroud)
nha*_*tdh 15
看起来这是plusOutCodingBat上的问题.
我有3个解决这个问题的方法,并为了好玩而写了一个新的流媒体解决方案.
从输入字符串中创建一个StringBuilder,并检查每个位置的单词.如果不匹配则替换字符,如果找到则跳过单词的长度.
public String plusOut(String str, String word) {
StringBuilder out = new StringBuilder(str);
for (int i = 0; i < out.length(); ) {
if (!str.startsWith(word, i))
out.setCharAt(i++, '+');
else
i += word.length();
}
return out.toString();
}
Run Code Online (Sandbox Code Playgroud)
这可能是初学者程序员的预期答案,尽管假设字符串不包含任何星体平面字符,它将由2个字符而不是1表示.
public String plusOut(String str, String word) {
return str.replaceAll(java.util.regex.Pattern.quote(word), "@").replaceAll("[^@]", "+").replaceAll("@", word);
}
Run Code Online (Sandbox Code Playgroud)
不是一个合适的解决方案,因为它假定字符串中没有出现某个字符或字符序列.
注意使用它Pattern.quote来防止word被方法解释为正则表达式语法replaceAll.
\Gpublic String plusOut(String str, String word) {
word = java.util.regex.Pattern.quote(word);
return str.replaceAll("\\G((?:" + word + ")*+).", "$1+");
}
Run Code Online (Sandbox Code Playgroud)
构建正则表达式\G((?:word)*+).,它或多或少地做了解决方案1正在做的事情:
\G 确保匹配从上一场比赛的开始处开始((?:word)*+)选出0或更多的实例word- 如果有的话,这样我们就可以将它们保留在替换中$1.这里的关键是占有量词*+,它强制正则表达式保留word它找到的任何实例.否则,当word出现在字符串末尾时,正则表达式将无法正常工作,因为正则表达式回溯匹配..将不会成为任何一部分word,因为前一部分已经连续出现word并且不允许回溯.我们将替换它+public String plusOut(String str, String word) {
return String.join(word,
Arrays.stream(str.split(java.util.regex.Pattern.quote(word), -1))
.map((String s) -> s.replaceAll("(?s:.)", "+"))
.collect(Collectors.toList()));
}
Run Code Online (Sandbox Code Playgroud)
我们的想法是拆分字符串word,对其余部分进行替换,然后word使用using String.join方法将它们连接起来.
Pattern.quote避免split将word正则表达式解释为正则表达式.由于split默认情况下会删除数组末尾的空字符串,因此我们需要-1在第二个参数中使用split这些空字符串.+.在Java 11中,我们可以使用s -> String.repeat(s.length()).这比你最初想象的要复杂一点,因为你不仅需要匹配字符,而且缺少特定的短语 - 否定的字符集是不够的.如果字符串是123,您将需要:
(?<=^|123)(?!123).*?(?=123|$)
Run Code Online (Sandbox Code Playgroud)
https://regex101.com/r/EZWMqM/1/
即 - 查看字符串开头或"123",确保当前位置后面没有123,然后懒惰重复任何字符,直到前瞻符合"123"或字符串结尾.这将匹配不在"123"子字符串中的所有字符.然后,您需要用a替换每个字符+,之后您可以使用appendReplacementa和a StringBuffer来创建结果字符串:
String inputPhrase = "123";
String inputStr = "abc123efg123123hij";
StringBuffer resultString = new StringBuffer();
Pattern regex = Pattern.compile("(?<=^|" + inputPhrase + ")(?!" + inputPhrase + ").*?(?=" + inputPhrase + "|$)");
Matcher m = regex.matcher(inputStr);
while (m.find()) {
String replacement = m.group(0).replaceAll(".", "+");
m.appendReplacement(resultString, replacement);
}
m.appendTail(resultString);
System.out.println(resultString.toString());
Run Code Online (Sandbox Code Playgroud)
输出:
+++123+++123123+++
Run Code Online (Sandbox Code Playgroud)
请注意,如果inputPhrase可以包含正则表达式中具有特殊含义的字符,则必须在连接到模式之前先将它们转义.
| 归档时间: |
|
| 查看次数: |
1895 次 |
| 最近记录: |