gpt4 book ai didi

java - 替换引号中的空格

转载 作者:行者123 更新时间:2023-11-29 06:17:38 24 4
gpt4 key购买 nike

我真的在这里与正则表达式作斗争。使用Java,我将如何去将引号(实际上是双引号)中的所有空格替换为另一个字符(或转义的空格"\ "),但是仅当短语以通配符结尾时才可以。

word1 AND "word2 word3 word4*" OR "word5 word6" OR word7




word1 AND "word2\ word3\ word4*" OR "word5 word6" OR word7

最佳答案

我认为最好的解决方案是使用正则表达式查找所需的带引号的字符串,然后替换正则表达式匹配项中的空格。像这样:

import java.util.regex.*;

class SOReplaceSpacesInQuotes {
public static void main(String[] args) {
Pattern findQuotes = Pattern.compile("\"[^\"]+\\*\"");

for (String arg : args) {
Matcher m = findQuotes.matcher(arg);

StringBuffer result = new StringBuffer();
while (m.find())
m.appendReplacement(result, m.group().replace(" ", "\\\\ "));
m.appendTail(result);

System.out.println(arg + " -> " + result.toString());
}
}
}


运行 java SOReplaceSpacesInQuotes 'word1 AND "word2 word3 word4*" OR "word5 word6*" OR word7'然后愉快地产生输出 word1 AND "word2 word3 word4*" OR "word5 word6*" OR word7 -> word1 AND "word2\ word3\ word4*" OR "word5\ word6*" OR word7,这正是您想要的。

模式为 "[^"]+\*",但是对于Java,必须转义反斜杠和引号。这与文字引号,任意数量的非引号, *和引号匹配,这正是您想要的。假设(a)不允许嵌入 \"转义序列,并且(b) *是唯一的通配符。如果您具有嵌入式转义序列,则使用 "([^\\"]|\\.)\*"(对于Java而言,转义为 \"([^\\\\\\"]|\\\\.)\\*\");如果您有多个通配符,请使用 "[^"]+[*+]";如果两者兼而有之,则以明显的方式将它们组合在一起。处理多个通配符只是在字符串的末尾让它们中的任何一个匹配。通过匹配引号后跟任意数量的非反斜杠,非引号字符或根本不包含反斜杠的反斜杠来处理转义序列。

现在,该模式将找到所需的带引号的字符串。然后,对于程序的每个参数,我们将它们全部匹配,并使用 m.group().replace(" ", "\\\\ "),将匹配的每个空格(带引号的字符串)替换为反斜杠和空格。 (此字符串为 \\-为什么不确定需要两个真实的反斜杠。)如果以前(我没有)没有见过 appendReplacementappendTail,请按照以下步骤进行: ,它们遍历整个字符串,替换与 appendReplacement的第二个参数匹配的内容,并将其全部附加到给定的 StringBuffer上。 appendTail调用对于捕获最后不匹配的内容是必需的。 documentation for Matcher.appendReplacement(StringBuffer,String)包含了一个很好的用法示例。



编辑:正如罗兰·伊利格(Roland Illig)所指出的那样,如果出现某些类型的无效输入(例如 a AND "b" AND *"c",将变为 a AND "b"\ AND\ *"c"),这将是一个问题。如果这是一种危险(或者将来有可能成为危险,那么很可能),那么您应该通过始终匹配引号来使其更加健壮,但是只有在引号以通配符结尾时才进行替换。只要您的报价始终正确配对就可以了,这是一个较弱的假设。产生的代码非常相似:

import java.util.regex.*;

class SOReplaceSpacesInQuotes {
public static void main(String[] args) {
Pattern findQuotes = Pattern.compile("\"[^\"]+?(\\*)?\"");

for (String arg : args) {
Matcher m = findQuotes.matcher(arg);

StringBuffer result = new StringBuffer();
while (m.find()) {
if (m.group(1) == null)
m.appendReplacement(result, m.group());
else
m.appendReplacement(result, m.group().replace(" ", "\\\\ "));
}
m.appendTail(result);

System.out.println(arg + " -> " + result.toString());
}
}
}


我们将通配符放在一个组中,并使其成为可选项,并使用 +?将引号的主体设为不愿意,这样它就将尽可能少地匹配,并让通配符被分组。这样,我们将匹配每对连续的引号,并且由于正则表达式引擎不会在匹配过程中重新启动,因此,我们只会匹配引号的内部而不是外部。但是,现在我们并不总是希望替换空格-我们只希望在有通配符的情况下进行替换。这很简单:测试一下组1是否为 null。如果是,则没有通配符,因此将字符串替换为其自身。否则,请更换空格。实际上, java SOReplaceSpacesInQuotes 'a AND "b d" AND *"c d"'会产生所需的 a AND "b d" AND *"c d" -> a AND "b d" AND *"c d",而 java SOReplaceSpacesInQuotes 'a AND "b d" AND "c d*"'执行替换以获取 a AND "b d" AND *"c d" -> a AND "b d" AND "c\ *d"

关于java - 替换引号中的空格,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4478038/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com