Java 或 Scala。如何将 \x22 等字符转换为字符串

Posted

技术标签:

【中文标题】Java 或 Scala。如何将 \\x22 等字符转换为字符串【英文标题】:Java or Scala. How to convert characters like \x22 into StringJava 或 Scala。如何将 \x22 等字符转换为字符串 【发布时间】:2018-04-12 10:10:58 【问题描述】:

我有一个如下所示的字符串:

\x22documentReferer\x22:\x22http:\x5C/\x5C/pikabu.ru\x5C/freshitems.php\x22

如何将其转换为可读的 JSON?

我发现了不同的慢速解决方案,例如 here with regEx

已经试过了:

URL.decode
StringEscapeUtils
JSON.parse // from different libraries 

例如,python 有简单的解决方案,例如从'string_escape' 解码

链接的可能重复项适用于 Python,我的问题是关于 Java 或 Scala

我现在使用的工作但也很慢的解决方案来自here:

 def unescape(oldstr: String): String = 
val newstr = new StringBuilder(oldstr.length)
var saw_backslash = false
var i = 0
while (i < oldstr.length) 
  
    val cp = oldstr.codePointAt(i)
    if (!saw_backslash) 
      if (cp == '\\') saw_backslash = true
      else newstr.append(cp.toChar)
     else 
      if (cp == '\\') 
        saw_backslash = false
        newstr.append('\\')
        newstr.append('\\')
       else 
        if (cp == 'x') 
          if (i + 2 > oldstr.length) die("string too short for \\x escape")
          i += 1
          var value = 0
          try
            value = Integer.parseInt(oldstr.substring(i, i + 2), 16)
          catch 
            case nfe: NumberFormatException =>
              die("invalid hex value for \\x escape")
          
          newstr.append(value.toChar)
          i += 1
        
        else 
          newstr.append('\\')
          newstr.append(cp.toChar)
        
        saw_backslash = false
      
    
  
  i += 1

    if (saw_backslash) newstr.append('\\')
    newstr.toString
  

private def die(msg: String) 
  throw new IllegalArgumentException(msg)

【问题讨论】:

你有没有尝试过?在我看来,没有研究 @Prashant 在你看来。我已经尝试过在描述和其他方面链接的慢速 您为 Python 链接了问题,我询问了 Scala 的 Java 解决方案。你读过这个问题吗? @Prashant 请解释链接重复项 关于 Python 和 OP 的可能重复链接问题表明他或她已尝试使用该答案中的指导但无济于事。应该保持打开状态。 【参考方案1】:

\x 用于转义 Python 和其他语言中的 ASCII 字符。在 Scala 和 Java 中,您可以使用 \u 转义 Unicode 字符。由于 ASCII 是 Unicode 的子集(如 here 所述),我们可以使用 unescapeJava 方法(在 StringEscapeUtils 中)以及一些简单的替换来添加 \u 转义字符和两个前导零:

import org.apache.commons.lang3.StringEscapeUtils
StringEscapeUtils.unescapeJava(x.replaceAll("""\\x""", """\\u00"""))

您还可以使用正则表达式查找转义序列并将其替换为适当的 ASCII 字符:

val pattern = """\\x([0-9A-F]2)""".r

pattern.replaceAllIn(x, m => m.group(1) match 
  case "5C" => """\\""" //special case for backslash
  case hex => Integer.parseInt(hex, 16).toChar.toString
)

这似乎更快,并且不需要外部库,尽管对于您的需要它仍然可能很慢。它可能也不涵盖某些边缘情况,但可能涵盖简单的需求。

我绝对不是这方面的专家,所以可能有更好的方法来处理这个问题。

【讨论】:

感谢您的回答!它可以工作,但仍然比我现在使用的要慢。 replaceAll 也使用正则表达式,所以我尝试使用 replace() 但性能同样缓慢。 @Soloveiko 我已经用更简单的解决方案更新了答案,该解决方案更快,但不那么强大。可能会给你一些新的想法。

以上是关于Java 或 Scala。如何将 \x22 等字符转换为字符串的主要内容,如果未能解决你的问题,请参考以下文章

在Scala中将字符串转换为运算符

将标头记录(或字符串/文件)添加到 Scala / Java 中的大文件中

Scala:将字符串转换为 Int 或 None

如何将字符串写入Scala Process?

如何将 x22之类的字符转换为字符串

在 Java(或 Scala)中迭代 HashMap 的 HashMap