marco
marco

Reputation: 1752

QRegularExpression: skip matching escaped tokens

I'm replacing a QString using QRegularExpression but I have a problem with escaped tokens.

For example: a "{aaa}" in the string should be replace with a "bbb" but a "\{aaa}" should be ignored and a "{aaa}" will be set (without the "\").

eg:

this is a test called {aaa} -> this is a test called bbb
this is a test called \{aaa} -> this is a test called {aaa}

I'm using

QString& replace(const QRegularExpression& re, const QString& after);

but I cannot find a way to skip an escaped match. I guess with a negative look-behind, but how?

Upvotes: 1

Views: 582

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627077

The pattern you came up with - (?<!\\){aaa} - will not match valid {aaa} that is preceded with a valid escaped backslash, \\{aaa}, see this demo.

What you need is a regex that will account for these escaped backslashes:

(?<!\\)(?:\\{2})*\K{aaa}

See the regex demo.

Details:

  • (?<!\\) - a negative lookbehind failing the match if there is a \ immediately to the left of the current location
  • (?:\\{2})* - zero or more occurrences of double backslash
  • \K - match reset operator discarding the text matched so far
  • {aaa} - a literal {aaa} substring.

In Qt, string literals may contain escape sequences, \n for a newline, \r for a carriage return, etc. To define a literal backslash (that is used to form regex escapes, regex operators, shorthand character classes), you need to double the backslash:

QRegularExpression re("(?<!\\\\)(?:\\\\{2})*\\K{aaa}")

Upvotes: 2

marco
marco

Reputation: 1752

I've found the solution:

QRegularExpression re(QString("(?<!\\\\)({aaa})")

I just missed that to match a backslash, 4 must be used.

Upvotes: 0

Related Questions