0

I'm currently working with NSRegularExpressions (regex), which I'm building a markdown regex.

I think that my approach on the way to change the text that matches the regex isn't the best one, and here's why.

I have created the following, as example:

UITextViewDelegate

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

    regularExpression()

    return true
}

func regularExpression() {
    // Some other regular expressions.... 

    let boldPattern = "\\*{2}([\\w\\d ]+)\\*{2}"
    do {
        let regex = try NSRegularExpression(pattern: boldPattern)
        let results = regex.matches(in: str, range: NSRange(str.startIndex..., in: str))

        _ = results.map {
            self.applyAttributes(toRange: $0.range, withType: .bold)
        }
    } catch let err{
        print("error:", err.localizedDescription)
    }
}

As you see above, in order for me to update the text as soon as the user types, I'm currently going through the text, for each inserted character, and analyze if there's any matching pattern (in this case to bold as ** some text **);

By doing this, as I go through typing the CPU usage goes from 3% to 25%, thus I think this isn't the best approach to take in.

What would be the best approach to apply NSRegularExpressions on-the-fly, as the user types? - is the current one I'm using the best one?

Thank you

Ivan Cantarino
  • 3,058
  • 4
  • 34
  • 73
  • You should initialize the regex outside the method that is called upon each key input event, `let regex = try NSRegularExpression(pattern: boldPattern)` should be declared before that, and then passed to the checking method. BTW, do not use `[\w\d]`, it is equal to `\w`. So, your pattern can be written as `"\\*{2}([\\w ]+)\\*{2}"` – Wiktor Stribiżew Mar 12 '18 at 18:11
  • @WiktorStribiżew thanks for the tip. I’ll do as you’ve suggested – Ivan Cantarino Mar 12 '18 at 19:07

1 Answers1

2

A really simple solution is to check if the inserted text contains *(asterisk) before call regularExpression method:

func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {

    if text.contains("*"){
        regularExpression()
    }

    return true
}
Alexandre Lara
  • 2,464
  • 1
  • 28
  • 35
  • hmm... I haven't thought on that, wow! And for each desired entry type I do the respective checks. Like for italics I check for `_` and so on. I'll give it a try :) – Ivan Cantarino Mar 12 '18 at 15:34