smeeb smeeb - 28 days ago 6
Scala Question

String replacing nested JSON in Scala

I have a Scala method that will be given a String like so:

"blah blah sediejdri \"foos\": {\"fizz\": \"buzz\"}, odedrfj49 blah"


And I need to strip the "foos JSON" out of it using pure Java/Scala (no external libs). That is, find the substring matching the pattern:

\"foos\" : {ANYTHING},


...and strip it out, so that the input string is now:

"blah blah sediejdri odedrfj49 blah"


The token to search for will always be
\"foos\"
, but the content inside the JSON curly braces will always be different. My best attempt is:

// Ex: "blah \"foos\": { flim flam }, blah blah" ==> "blah blah blah", etc.
def stripFoosJson(var : toClean : String) : String = {
val regex = ".*\"foos\" {.*},.*"
toClean.replaceAll(regex, "")
}


However I my regex is clearly not correct. Can anyone spot where I'm going awry?

Answer

Here are 2 solutions I came up with, hope it helps. I think you forgot to handle possible spaces with \s* etc.

object JsonStrip extends App {

    // SOLUTION 1, hard way, handles nested braces also:
    def findClosingParen(text: String, openPos: Int): Int = {
        var closePos = openPos
        var parensCounter = 1 // if (parensCounter == 0) it's a match!
        while (parensCounter > 0 && closePos < text.length - 1) {
            closePos += 1
            val c = text(closePos)
            if (c == '{') {
                parensCounter += 1
            } else if (c == '}') {
                parensCounter -= 1
            }
        }
        if (parensCounter == 0) closePos else openPos
    }

    val str = "blah blah sediejdri \"foos\": {\"fizz\": \"buzz\"}, odedrfj49 blah"
    val indexOfFoos = str.indexOf("\"foos\"")
    val indexOfFooOpenBrace = str.indexOf('{', indexOfFoos)
    val indexOfFooCloseBrace = findClosingParen(str, indexOfFooOpenBrace)
    // here you would handle if the brace IS found etc...
    val stripped = str.substring(0, indexOfFoos) + str.substring(indexOfFooCloseBrace + 2)
    println("WITH BRACE COUNT: " + stripped)

    // SOLUTION 2, with regex:
    val reg = "\"foos\"\\s*:\\s*\\{(.*)\\}\\s*,\\s*"
    println("WITH REGEX: " + str.replaceAll(reg, ""))
}
Comments