【问题标题】:Does Guava provide a method to unescape a String?Guava 是否提供了一种对字符串进行转义的方法?
【发布时间】:2015-12-04 15:05:46
【问题描述】:

我需要转义 String 中的特殊字符。

Guava 提供了 Escaper 类,它正是这样做的:

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('<', "&lt;")
        .addEscape('>', "&gt;")
        .build();

在这里,您可以安全地转义任何文本,将其合并到 HTML 页面中并随时取消转义以显示它,因为您涵盖了所有可能的歧义。

总之,我不明白为什么取消转义如此有争议。我认为正确使用这个类,了解他的数据并避免歧义是开发人员的责任。 逃避,顾名思义,意味着你最终需要逃避。否则就是混淆或其他概念。

【问题讨论】:

    标签: java guava


    【解决方案1】:

    不,它没有。显然,这是故意的。引用this discussion Chris Povirk 的回答:

    我对取消转义的用例不太清楚。一般不会 甚至可以在没有解析器的情况下识别转义的源文本 理解语言的人。例如,如果我有以下 输入:

    String s = "foo\n\"bar\"\n\\";
    

    那么我的解析器必须已经理解 \n\"\\ 才能 确定...

    foo\n\"bar\"\n\\
    

    ...是要“未转义”的文本。换句话说,它必须做到 已经逃不掉了。情况与 HTML 和其他类似 格式:我们不需要解析器,而是需要解析器。

    看来你得自己动手了。

    【讨论】:

    • 我不明白。就我而言,要未转义的文本是众所周知的:它位于escapedStr。我不需要解析Java代码,我只需要在一个简单的String中删除转义序列。
    • 你能给我们更多的背景信息吗?在转义字符串和取消转义字符串之间,您如何处理字符串?取消转义后如何处理它?
    • @ChrisPovirk 您可能想对该问题发表评论,以便 OP 得到通知。
    • @ChrisPovirk 我需要通过使用分隔符(-_ 等)连接值来序列化一个值列表。如果一个值包含给定的分隔符,我需要将其替换为 safe 字符,这样我就可以在反序列化时拆分它们并将 safe 字符替换为原始文字。我目前正在使用一个简单的Map 并对其进行迭代,将键(分隔符)替换为值(safe 字符)。在反序列化时,我只是恢复Map 并再次执行此操作。我找到了 Escaper 类,我认为它可以满足我的需要并为我保存这个样板代码。
    • @ChrisPovirk 恕我直言,Escaper 应该是对称的。如果实现了 unescape 对应项,我认为它应该是 Escaper 类的方法,其中包含所有有用的信息。当然,如果没有人需要,它可能不值得付出努力。正如您所提到的,大多数情况下,取消转义是由 其他东西 完成的,例如浏览器。如果您决定在 Guava 中引入此功能,请告诉我,我很乐意提供帮助。
    【解决方案2】:

    如果您只需要取消转义 HTML 实体、Unicode 字符和控制字符,例如 \n\t,您可以简单地使用来自 Apache Commons LangStringEscapeUtils 类。

    【讨论】:

      【解决方案3】:

      如果有人需要单个字符转义符,下面是一个非常简单的实现:

      @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();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-09-24
        • 1970-01-01
        相关资源
        最近更新 更多