I wrote this function in scala that uses tail recursion to remove nested blocks from a text.
Usage examples:
removeBlocks("123{456}789", "{", "}") yields "123789"
removeBlocks("123{a{b{c}b}a}789", "{", "}") yields "123789"
removeBlocks("123<div>456</div>789", "<div>", "</div>") yields "123789"
removeBlocks("123<<<div><<<</div>>>789", "<div>", "</div>") yields "123<<>>789"
This is one of my first attempts in a functional language, and I'm deeply dissatistied with my code. It's too long, too nested, and could probably be made more readable. I'm coming from C# and hope to be forgiven for this bad functional code. I'll be happy to hear how it can be improved.
def removeBlocks(text: String, startMarker: String, endMarker: String) = {
val startMarkerSize = startMarker.size
val endMarkerSize = endMarker.size
val startMarkerHead = startMarker.head
val endMarkerHead = endMarker.head
def removeBlocksAcc(s: String, acc: String, nestingLevel: Int): String =
if (s.isEmpty) acc
else {
val (startMarkerCandidate, tail1) = s.splitAt(startMarkerSize)
if (startMarkerCandidate == startMarker)
removeBlocksAcc(tail1, acc, nestingLevel + 1)
else {
val (endMarkerCandidate, tail2) = s.splitAt(endMarkerSize)
if (endMarkerCandidate == endMarker)
removeBlocksAcc(tail2, acc, math.max(nestingLevel - 1, 0))
else {
val (safePart, candidate) = s.tail.span(c => c != startMarkerHead && c != endMarkerHead)
if (nestingLevel == 0)
removeBlocksAcc(candidate, acc + s.head + safePart, nestingLevel)
else
removeBlocksAcc(candidate, acc, nestingLevel)
}
}
}
removeBlocksAcc(text, "", 0)
}
removeBlocks
example. Wouldn't you be left with 123<<<789 – Ogen Nov 28 '14 at 0:33