The logging facility for our C++ project is about to be refactored to use repeated left-shift operators (in the manner of Qt's qDebug()
syntax) instead of printf-style variadic functions.
Suppose the logging object is called logger
. Let's say we want to show the ip and port of the server we connected to. In the current implementation, the usage is:
logger.logf("connected to %s:%d", ip, port);
After the refactor, the above call would become:
logger() << "connected to" << ip << ":" << port;
Manually replacing all these calls would be extremely tedious and error-prone, so naturally, I want to use a regex. As a first pass, I could replace the .logf(...)
call, yielding
logger() "connected to %s:%d", ip, port;
However, reformatting this string to the left-shift syntax is where I have trouble. I managed to create the separate regexes for capturing printf placeholders and comma-delimited arguments. However, I don't know how to properly correlate the two.
In order to avoid repetition of the fairly unwieldy regexes, I will use the placeholder (printf)
to refer to the printf placeholder regex (returning the named group token
), and (args)
to refer to the comma-delimited arguments regex (returning the named group arg
). Below, I will give the outputs of various attempts applied to the relevant part of the above line, i.e.:
"connected to %s:%d", ip, port
/(printf)(args)/g
produces no match./(printf)*(args)/g
produces two matches, containingip
andport
in the named grouparg
(but nothing intoken
)./(printf)(args)*/g
achieves the opposite result: it produces two matches, containing%s
and%d
in the named grouptoken
, but nothing inarg
./(printf)*(args)*/g
returns 3 matches: the first two contain%s
and%d
intoken
, the third containsport
inarg
. However, regexp101 reports "20 matches - 207 steps" and seems to match before every character.I figured that perhaps I need to specify that the first capturing group is always between double quotes. However, neither
/"(printf)"(args)/g
nor/"(printf)(args)/g
produce any matches./(printf)"(args)/g
produces one (incorrect) match, containing%d
in grouptoken
andip
inarg
, and substitution consumes the entire string between those two strings (so entering#
for the substitution string results in"connected to %s:#, port
. Obviously, this is not the desired outcome, but it's the only version where I could at least get both named groups in a single match.
Any help is greatly appreciated.
Edited to correct broken formatting