score:2

Accepted answer

i guess tt should be a reverse to flatmap with a function f:seq[char] => char. does it make sense ?

not really. what should your inverse function f:seq[char] => char return on "abc"? it should apply to any sequence of characters and return a single character. you could try using partialfunction[seq[char], char] instead, but you'll run into other problems. do you apply it to every subsequence of your input?

the more general solution would be to use foldleft with the accumulator type containing both the built-up part of the result and the escaping sequence, something like (untested):

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" -> "<", ...)

(it's much more efficient to use stringbuilders for the accumulators, but this is simpler to understand.)

but for this specific case you could just split the string on &, then split each part except first on ;, and get the parts you want this way.

score:1

this seems to be a follow-up to my own answer to the question whose follow-up this question is... use scala.xml.utility.unescape:

val sb = new stringbuilder
scala.xml.utility.unescape("amp", sb)
println(sb.tostring) // prints &

or if you just want to unescape once and throw away the stringbuilder instance:

scala.xml.utility.unescape("amp", new stringbuilder).tostring // returns "&"

this just parses individual escapes; you'll have to build a parser of entire xml strings around it yourself—the accepted answer seems to provide that bit but fails to not reinvent the scala.xml.utility wheel— or use something from scala.xml instead.


Related Query

More Query from same tag