如何在String.Format中转义%?


445

我正在我的strings.xml文件中存储一个SQL查询,我想用它String.Format来构建代码中的最终字符串。该SELECT语句使用了一个赞,就像这样:

SELECT Field1, Field2 FROM mytable WHERE Field1 LIKE '%something%'

为了格式化,我将“ something”替换为%1 $ s,因此它变为:

SELECT Field1, Field2 FROM mytable WHERE Field1 LIKE \'%%1$s%\'

我用反斜杠转义了单引号。但是,我无法逃脱%符号。

如何在我的strings.xml文件中包含一个like语句?


不要忘记正确地逃脱%s。
塞瓦·阿列克谢耶夫


他们将注入自己的数据库,在这里无所谓;)
Matthew

7
好吧,即使它是您自己的数据库,也可能会意外地编写执行不良操作的查询。或者只是编写不编译的查询。准备查询是一个很好的习惯。
Rauni Lillemets 2014年

尽管它比String.format()您可能考虑使用的速度慢MessageFormat()
ccpizza

Answers:



14

为了补充先前说明的解决方案,请使用:

str = str.replace("%", "%%");

1
这将替换已加倍的%。请阅读其他答案。
托拉勒

1
@Toilal为什么有人会逃脱已经逃脱的东西?如果他愿意,为什么不实际做呢?也许他打算有两个%号,所以正确的转义形式为'%%%%'
DavidBalažic18年

2

这是一个更强大的正则表达式替换,不会替换输入中已加倍的%%。

str = str.replaceAll("(?:[^%]|\\A)%(?:[^%]|\\z)", "%%");

-3

如果您需要在字符串中转义多个%并且已经转义了某些字符,这是一个选项。

(?:[^%]|^)(?:(%%)+|)(%)(?:[^%])

要在将消息传递给String.format之前对其进行清理,可以使用以下命令

Pattern p = Pattern.compile("(?:[^%]|^)(?:(%%)+|)(%)(?:[^%])");
Matcher m1 = p.matcher(log);

StringBuffer buf = new StringBuffer();
while (m1.find())
    m1.appendReplacement(buf, log.substring(m1.start(), m1.start(2)) + "%%" + log.substring(m1.end(2), m1.end()));

// Return the sanitised message
String escapedString = m1.appendTail(buf).toString();

这适用于任意数量的格式字符,因此它将%替换为%%,%%%替换为%%%%,%%%%%替换为%%%%%%等。

它将留下任何已经转义的字符(例如,%%,%%%%等)


8
“到目前为止,我不敢相信这不是一个简单的解决问题。” <<在接受了简单的解决方案的6年后,您回答了。
AjahnCharles
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.