0

there is a line from the console that needs to be displayed in the application. Can anyone suggest how to clear the line?

"\u{1B}[2K\u{1B}[1G\u{1B}[32msuccess\u{1B}[39m Checking for changed pages - 0.000s"

And get in the end:

"success Checking for changed pages - 0.000s"

2 Answers2

3

Use the regular expression mentioned in this answer

let str = "\u{1B}[2K\u{1B}[1G\u{1B}[32msuccess\u{1B}[39m Checking for changed pages - 0.000s"

let regex = try! NSRegularExpression(pattern: "\u{1B}(?:[@-Z\\-_]|\\[[0-?]*[ -/]*[@-~])")
let range = NSRange(str.startIndex..<str.endIndex, in: str)

let cleaned = regex.stringByReplacingMatches(in: str, options: [], range: range, withTemplate: "")
print(cleaned) // "success Checking for changed pages - 0.000s"
Gereon
  • 17,258
  • 4
  • 42
  • 73
1

@Gereon's answer is one way to skin the cat. Here's another:

let s = "\u{1B}[2K\u{1B}[1G\u{1B}[32msuccess\u{1B}[39m Checking for changed pages - 0.000s"

guard let r = s.range(of: "Checking for changed pages") else {
    fatalError("Insert code for what to do if the substring isn't found")
}
let cleaned = "success " + String(s[r.lowerBound...])

Here I just literally insert the "success". But if you really need to verify that it's in the string, that can be done too.

guard let r = s.range(of: "Checking for changed pages"), s.contains("success")
else
{
    fatalError("Insert code for what to do if the substring isn't found")
}

To solve the more general problem of removing ANSI escape sequences, you'll need to parse them. Neither my simple solution, nor the regex solution will do it. You'll need to explicitly look for the possible valid codes that follow the escapes.

let escapeSequences: [String] =
    [/* list of escape sequnces */
        "[2K", "[1G", "[32m", "[39m", // etc...
    ]

let escapeChar = Character("\u{1B}")
var result = ""
var i = s.startIndex
outer: while i != s.endIndex
{
    if s[i] == escapeChar
    {
        i = s.index(after: i)
        for sequence in escapeSequences {
            if s[i...].hasPrefix(sequence) {
                i = s.index(i, offsetBy: sequence.distance(from: sequence.startIndex, to: sequence.endIndex))
                continue outer
            }
        }
    }
    else { result.append(s[i]) }
    i = s.index(after: i)
}

print(result)

The thing is, I think ANSI escape sequences can be combined in interesting ways so that what would be multiple escapes can be merged into a single one in some cases. So it can be more complex than just the simple parser I presented.

Chip Jarred
  • 2,600
  • 7
  • 12