[英]How to implement “unescape” in Scala?
這是我先前問題的跟進
多虧了答案,我才意識到escape
函數實際上是一個帶有參數f:Char => Seq[Char]
的flatMap
,用於將轉義字符映射到轉義序列(請參見答案)。
現在,我想知道如何將unescape
實現為反向操作以進行escape
。 我猜tt應該與參數f:Seq[Char] => Char
flatMap
相反。 是否有意義 ? 您如何建議實施unescape
?
我想tt應該是帶有函數f:Seq [Char] => Char的flatMap的反向版本。 是否有意義 ?
並不是的。 您的反函數f:Seq[Char] => Char
在"abc"
上返回什么? 它應適用於任何字符序列並返回單個字符。 您可以嘗試使用PartialFunction[Seq[Char], Char]
代替,但是會遇到其他問題。 您是否將其應用於輸入的每個子序列?
更通用的解決方案是將foldLeft
與累加器類型一起使用,該累加器類型既包含結果的累積部分,又包含轉義序列,例如(未經測試):
def unescape(str: String) = {
val result = str.foldLeft[(String, Option[String])](("", None)) { case ((acc, escapedAcc), c) =>
(c, escapedAcc) match {
case ('&', None) =>
(acc, Some(""))
case (_, None) =>
(acc + c, None)
case ('&', Some(_)) =>
throw new IllegalArgumentException("nested escape sequences")
case (';', Some(escapedAcc1)) =>
(acc + unescapeMap(escapedAcc1), None)
case (_, Some(escapedAcc1)) =>
(acc, Some(escapedAcc1 + c))
}
}
result match {
case (escaped, None) =>
escaped
case (_, Some(_)) =>
throw new IllegalArgumentException("unfinished escape sequence")
}
}
val unescapeMap = Map("amp" -> "&", "lt" -> "<", ...)
(對累加器使用StringBuilder
效率更高,但這更容易理解。)
但是對於這種特定情況,您可以只在&
上分割字符串,然后分割除第一部分外的每個部分;
,並以此方式獲取所需零件。
這似乎是我 對該問題的回答的后續問題 , 該問題的后續問題是...使用scala.xml.Utility.unescape
:
val sb = new StringBuilder
scala.xml.Utility.unescape("amp", sb)
println(sb.toString) // prints &
或者,如果您只想取消轉義並丟棄StringBuilder
實例,則:
scala.xml.Utility.unescape("amp", new StringBuilder).toString // returns "&"
這只是解析單個逃生; 您必須自己圍繞它構建整個XML字符串的解析器-公認的答案似乎提供了這一點,但是未能重新發明scala.xml.Utility
或改用scala.xml
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.