LogicStuff LogicStuff - 1 month ago 18
C++ Question

QRegularExpression - find match with captured length backwards

I can find previous match with this, but what I can't do, is to capture the length of the matched string:

int pos = 0;

if((pos = text.lastIndexOf(QRegularExpression(pattern), cursorPosition - 1)) != -1))
cout << "Match at position: " << pos << endl;


I can capture the length of the match with
QRegularExpressionMatch
, but I could not find any flag/option in the
QRegularExpression
nor
QRegularExpressionMatch
classes that would change the direction of the search. (I don't mean to reverse the pattern, but finding the first match before a certain position in a string.)

Example (I want to find not-even-regex
"hello"
):

hello world hello
^
start (somewhere in the middle)


And this should be the matched section:

hello world hello
^ ^
start end


Thank you in advance.

Answer

Note that in Qt5 QRegExp != QRegularExpression and I'm much more familiar with QRegExp. That said, I can't see a way to do what you want with QRegularExpression or QRegularExpression::match().

I would instead use QString::indexOf to search forwards and QString::lastIndexOf to search backwards. You can do this with either QRegExp or QRegularExpression if you just want to find the offset.

For example,

int pos = 8;
QString text = "hello world hello";
QRegularExpression exp("hello");

int bwd = text.lastIndexOf(exp, pos);   //bwd = 0
int fwd = text.indexOf(exp, pos);       //fwd = 12

//"hello world hello"
// ^       ^   ^
//bwd     pos fwd

You, however, also want to use the captured text, not just know where it is. This is where QRegularExpression seems to fail. As far as I can tell, there is no lastMatch() to retrieve the matched string after calling QString::lastIndexOf() QRegularExpress.

If you use a QRegExp instead, however, you can do this:

int pos = 8;
QString text = "hello world hello";
QRegExp exp("hello");

int bwd = text.lastIndexOf(exp, pos);   //bwd = 0
int fwd = text.indexOf(exp, pos);       //fwd = 12

//"hello world hello"
// ^       ^   ^
//bwd     pos fwd

int length = exp.cap(0).size();     //6... exp.cap(0) == "hello"
//or, alternatively
length = exp.matchedLength();       //6

The QRegExp object that you pass to the QString method gets updated with the captured string(s), which you can then use and manipulate. I can't imagine that they forgot to do that with QRegularExpression, but it looks like they might have.