Qt wiki will be updated on October 12th 2023 starting at 11:30 AM (EEST) and the maintenance will last around 2-3 hours. During the maintenance the site will be unavailable.

QTextDocument Block Boundary QRegExp

From Qt Wiki
Jump to navigation Jump to search

Matching over Block boundaries using QRegExp on QTextDocument

(formerly known as QTextDocument-Line-ending-and-Advanced-regular-expression-support)
Experimental

I've picked from QtForum itself. It's progressive article. I will update more when I will achieve something.

The QTextDocument::find(QRegExp) method will not attempt to match across a block boundary. As a result, although the QRegExp doc says that is matched by .* and by \s, one can never get a match to in a QPlainTextEdit document. The \n is end of block and the search never spans a block. Thus it seems impossible for a pattern like

.*

to find a match when the markup begins on one line and ends on another.

There is a way around this. The restriction is in QTextDocument. QRegExp does perform as documented when it is applied to a QString. So the following code can apply a general QRegExp to a document. This is using PyQt4; the translation to C++ should be clear. Given is a QPlainTextEdit qpte whose cursor is the starting point for the search. Also given is a QRegExp qrxp that has been prepared with a search pattern such as <b>.*</b> and its minimal and case switches set.

start_tc = qpte.textCursor() # cursor with starting position
range_tc = QTextCursor(start_tc) # make a copy linked to same doc
range_tc.movePosition(QTextCursor.End) # point to end of doc

range_tc.setPosition(start_tc.selectionStart(),QTextCursor.KeepAnchor) # select text between start and end cursor
hit_pos = qrxp.indexIn(range_tc.selectedText()) # apply regexp to (part of) the document as a QString

if hit_pos > 1 : # first occurrence at hit_pos offset
  find_tc = QTextCursor(start_tc) # another cursor
  find_tc.setPosition(start_tc.selectionStart()+hit_pos) # point to hit
  find_tc.movePosition(QTextCursor.Right, QTextCursor.KeepAnchor, qrxp.matchedLength()) # select matched text
  qpte.setTextCursor(find_tc) # match visible to user