Guava 是否提供了对字符串进行转义的方法?
Does Guava provide a method to unescape a String?
我需要转义 String
.
中的特殊字符
Guava 提供了 Escaper
class,它正是这样做的:
Escaper escaper = Escapers.builder()
.addEscape('[', "\[")
.addEscape(']', "\]")
.build();
String escapedStr = escaper.escape("This is a [test]");
System.out.println(escapedStr);
// -> prints "This is a \[test\]"
现在我有一个转义的 String
,我需要取消转义它,但我在 Guava 中找不到任何东西可以做到这一点。
我期待 Escaper
有一个 unescape()
方法,但事实并非如此。
编辑:我知道取消转义可能很棘手,甚至在某些无意义的情况下是不可能的。
例如,这种 Escaper
用法可能会导致歧义:
Escaper escaper = Escapers.builder()
.addEscape('@', " at ")
.addEscape('.', " dot ")
.build();
除非转义数据仅包含电子邮件地址,否则您无法通过取消转义来安全地取回您的数据。
安全使用 Escaper
的一个很好的例子是 HTML 个实体:
Escaper escaper = Escapers.builder()
.addEscape('&', "&")
.addEscape('<', "<")
.addEscape('>', ">")
.build();
在这里,您可以安全地转义任何文本,将其合并到 HTML 页面中,并随时 取消转义 以显示它,因为您涵盖了所有可能的歧义.
总而言之,我不明白为什么转义如此有争议。我认为开发人员有责任正确使用此 class,了解他的数据并避免歧义。
根据定义,转义意味着您最终将需要转义。否则就是混淆或其他概念。
不,不是。显然,这是故意的。引用 this discussion Chris Povirk 的回答:
The use case for unescaping is less clear to me. It's generally not
possible to even identify the escaped source text without a parser
that understands the language. For example, if I have the following
input:
String s = "foo\n\"bar\"\n\";
Then my parser has to already understand \n
, \"
, and \
in order to
identify that...
foo\n\"bar\"\n\
...is the text to be "unescaped." In other words, it has to do the
unescaping already. The situation is similar with HTML and other
formats: We don't need an unescaper so much as we need a parser.
看来你得自己动手了。
如果您只需要转义 HTML 实体、Unicode 字符和控制字符,例如 \n
或 \t
,您可以简单地使用 StringEscapeUtils class from Apache Commons Lang.
万一有人需要单个字符转义器,下面是一个非常简单的实现:
@Nonnull
public String unescape(@Nonnull String text) {
CharacterIterator i = new StringCharacterIterator(text);
StringBuilder result = new StringBuilder(text.length());
for (char c = i.first(); c != DONE; c = i.next()) {
if (c == escaped) {
result.append(i.next());
} else {
result.append(c);
}
}
return result.toString();
}
我需要转义 String
.
Guava 提供了 Escaper
class,它正是这样做的:
Escaper escaper = Escapers.builder()
.addEscape('[', "\[")
.addEscape(']', "\]")
.build();
String escapedStr = escaper.escape("This is a [test]");
System.out.println(escapedStr);
// -> prints "This is a \[test\]"
现在我有一个转义的 String
,我需要取消转义它,但我在 Guava 中找不到任何东西可以做到这一点。
我期待 Escaper
有一个 unescape()
方法,但事实并非如此。
编辑:我知道取消转义可能很棘手,甚至在某些无意义的情况下是不可能的。
例如,这种 Escaper
用法可能会导致歧义:
Escaper escaper = Escapers.builder()
.addEscape('@', " at ")
.addEscape('.', " dot ")
.build();
除非转义数据仅包含电子邮件地址,否则您无法通过取消转义来安全地取回您的数据。
安全使用 Escaper
的一个很好的例子是 HTML 个实体:
Escaper escaper = Escapers.builder()
.addEscape('&', "&")
.addEscape('<', "<")
.addEscape('>', ">")
.build();
在这里,您可以安全地转义任何文本,将其合并到 HTML 页面中,并随时 取消转义 以显示它,因为您涵盖了所有可能的歧义.
总而言之,我不明白为什么转义如此有争议。我认为开发人员有责任正确使用此 class,了解他的数据并避免歧义。 根据定义,转义意味着您最终将需要转义。否则就是混淆或其他概念。
不,不是。显然,这是故意的。引用 this discussion Chris Povirk 的回答:
The use case for unescaping is less clear to me. It's generally not possible to even identify the escaped source text without a parser that understands the language. For example, if I have the following input:
String s = "foo\n\"bar\"\n\";
Then my parser has to already understand
\n
,\"
, and\
in order to identify that...foo\n\"bar\"\n\
...is the text to be "unescaped." In other words, it has to do the unescaping already. The situation is similar with HTML and other formats: We don't need an unescaper so much as we need a parser.
看来你得自己动手了。
如果您只需要转义 HTML 实体、Unicode 字符和控制字符,例如 \n
或 \t
,您可以简单地使用 StringEscapeUtils class from Apache Commons Lang.
万一有人需要单个字符转义器,下面是一个非常简单的实现:
@Nonnull
public String unescape(@Nonnull String text) {
CharacterIterator i = new StringCharacterIterator(text);
StringBuilder result = new StringBuilder(text.length());
for (char c = i.first(); c != DONE; c = i.next()) {
if (c == escaped) {
result.append(i.next());
} else {
result.append(c);
}
}
return result.toString();
}