Qt World Summit: Register Today!

QTextDocument find does not fill in the passed QRegexp?

  • In a QPlainTextEdit, I pass a QRegexp to a QTextDocument find method: tc = self.document().find(re,tc).

    The good news is, the search succeeds, and it returns a QTextCursor that is not null, indeed one that selects the first instance of the matched text.

    The bad news is that the regex that I passed is not updated. re.matchedLength() returns -1, and re.cap(0) returns a null string. This is not good because I cannot extract sub-matches using re.cap(), or use the re for replacement.

    Am I overlooking something obvious? Is document.find(re,cursor) not the way to do regex find/replace in a document?

  • It can't update the reg exp, as it gets a const reference.
    But you can get the text out of the document using the text cursor and then use standard QRegExp stuff with a QString.

  • So I want to extend my PlainTextEdit with a regex find/replace feature. Tell me if I am understanding this correctly:

    Use hitCursor=self.document().find(re,startCursor) to find the next hit.

    Set hitCursor as the edit cursor to highlight the hit and make it visible.

    If the user specified Replace,

    1, pull the text out with foundString = hitCursor.selectedText()

    2, perform the replace with foundString.replace(re, repString)

    3, put the updated text back with hitCursor.insertText(foundString)

    Is that approximately the intended process?

  • I'm not 100% sure <bout the method names, but in general yes

  • dcortesi: For plain old find and replace, it's much simpler:
    hitCursor=document.find(re, cursor) // text matching the regexp is selected
    hitCursor.insertText(repString) // selected text is replaced

  • Yes, that would be the sequence for non-regex find "foo" replace "bar" or for a find of a regex pattern with no replacement.

    I was describing regex find/replace where the replacement string can contain \1 etc references to captured text. There you definitely need the find to prepare the QRegexp with captured substrings, and QString.replace() to carry out the replacement.

    The document's find doesn't fill in the regex object, so in the case where the user commands replace, it seems you have to pull out the matched text and do the find a second time to set up the QRegExp for replacing. The match is guaranteed on the second find, as it is being applied to exactly what the regex matched an instant before, and presumably it is quicker. Just a bit of extra trouble.

  • dcortesi: You're correct. I didn't think about \1s in the replacement string.

Log in to reply