Solved QRegularExpressionMatch
-
Here are two example lines containing data. I had to sanitize it for posting - the instrument names are actually very specific and have mostly to do with pressures and temperatures - changing the pattern for the specific names I think I can handle. The amount of data in a line (number of reporting instruments) can actually be much longer - I shortened them for brevity:
2017-10-19 14:08:58,325 TRACE [Publisher] C.DataPublisher [DataPublisher.java:159] Publishing {Instrument12=-900.0, Instrument0=82.4, Instrument11=-900.0, Instrument1=131.16875000000005, Instrument2=1.0, Instrument13=0.0, Instrument3=120.091247064, Instrument6=-0.9, Instrument22, Instrument4=83.91875000000005, Instrument12Status=1.0, Instrument13Status=1.0}
2017-10-19 14:08:58,825 TRACE [Publisher] C.DataPublisher [DataPublisher.java:159] Publishing {Instrument0=82.4, Instrument11=-900.0, Instrument1=135.33125000000007, Instrument3=120.091247064, Instrument4=83.91875000000005, Instrument22, Instrument23=-900.0, Instrument31=-900.0}Each new line starts with a date and timestamp.
-Scott
-
If they are not nested (i.e. you never have
{Instrument0=82.4,{Instrument11=-900.0, Instrument1=135.33125000000007}, Instrument4=83.91875000000005}
) then you can use:const QString input = "2017-10-19 14:08:58,325 TRACE [Publisher] C.DataPublisher [DataPublisher.java:159] Publishing {Instrument12=-900.0, Instrument0=82.4, Instrument11=-900.0, Instrument1=131.16875000000005, Instrument2=1.0, Instrument13=0.0, Instrument3=120.091247064, Instrument6=-0.9, Instrument22, Instrument4=83.91875000000005, Instrument12Status=1.0, Instrument13Status=1.0}" "2017-10-19 14:08:58,825 TRACE [Publisher] C.DataPublisher [DataPublisher.java:159] Publishing {Instrument0=82.4, Instrument11=-900.0, Instrument1=135.33125000000007, Instrument3=120.091247064, Instrument4=83.91875000000005, Instrument22, Instrument23=-900.0, Instrument31=-900.0}"; const QRegularExpression filterJunk(QStringLiteral("{(.+?)}")); const QRegularExpression instrumentRegExp(QStringLiteral(R"**(,?\s*Instrument(\d+)(?:Status)?\s*(?:=\s*([-+]?\d*\.?\d+(?:[eE][-+]?\d+)?))?)**"),QRegularExpression::CaseInsensitiveOption); auto i = filterJunk.globalMatch(input); while (i.hasNext()) { auto j= instrumentRegExp.globalMatch(i.next().capturedRef(1)); while (j.hasNext()) { const auto match = j.next(); QString result = QStringLiteral("Instrument: %1").arg(match.capturedRef(1).toInt()); if(match.lastCapturedIndex()>1) result += QStringLiteral(" Value: %1").arg(match.capturedRef(2).toDouble()); qDebug() << result ; } }
-
VRonin strikes again :D
-
For sure! Thanks VRonin.
A couple more questions - is it possible to pass in a variable as part of the regex matching line?
Also I don't seem to have the QRegularExpression Tool example (mentioned above). I'm using: Qt Creator 4.2.1 Based on Qt 5.8.0 (MSVC 2015, 32 bit)
Do I need to update my IDE to get it?
-Scott
-
is it possible to pass in a variable as part of the regex matching line?
can you explain better? maybe with an example?
Also I don't seem to have the QRegularExpression Tool example (mentioned above).
I use https://regex101.com/ same principle, better colours and allows you to unit-test too
-
Sorry, yes - I mean in the regular expression line:
instrumentRegExp(R"(,?\sInstrument(\d+)(?:Status)?\s(?:=\s*([-+]?\d*.?\d+(?:[eE][-+]?\d+)?))?)"
where its looking for an Instrument, is there a way to do something like this:
instrumentRegExp(R"(,?\sMyStringVariableHere(\d+)(?:Status)?\s(?:=\s*([-+]?\d*.?\d+(?:[eE][-+]?\d+)?))?)"
Regarding regular expression testing, I have realized that my text editor supports regex searching. I think it would be just a few tweaks to move them from there to QT.
Thanks again!
-
@MScottM said in QRegularExpressionMatch:
where its looking for an Instrument, is there a way to do something like this:
instrumentRegExp(R"(,?\sMyStringVariableHere(\d+)(?:Status)?\s(?:=\s*([-+]?\d*.?\d+(?:[eE][-+]?\d+)?))?)**"Well, just insert them as a variable to a
QString
before you pass the QString toQRegularExpression()
.QString myString("Static text with %1 some %2 variables").arg("foo").arg("bar");
-
Dang...geniuses...all of you.
Thanks! Will be testing tonight.
-
Side note:
@Joel-Bodenmann Let's stare into the abyss of
arg().arg()
: http://doc.qt.io/qt-5/qstring.html#arg-12 -
@VRonin That was interesting - didn't know about that one :p
-
You're a overplaying it a bit, aren't you? :)
I mean I knew of that pitfall, but there's nothing wrong in usingarg().arg()
as long as you're aware of this peculiarity, right? -
Warning: philosophical talk below.
I'm actually surprised to hear this from you, @kshegunov. I used
arg
above so I'm not 100% dogmatic on it but lets take a good look at it:arg
is a search and replace so it's slower thanQString::operator+
(if you concatenate a lot you can useoperator%(const QString&,const QString&)
inQStringBuilder
). This should be reason enough not to use it. If you add thearg().arg()
pitfall, that applies to any string you don't have complete control over all the aspect of input, it makes it almost evil.The only reason to use
arg()
I can see is internationalisation, but, even then, you have to take care of just usingarg(const QString&)
as numbers shown to the user should be processed byQLocale
and be mindful that if you callarg
more than once on the same string you are opening yourself to a translator possibly introducing what looks like a logic bug in your code -
Success!!
This piece of code is working now! Nearly exactly as VRonin posted...Plus I learned something from the discussion above: I have a lot to learn :)
I wanted to ask about the capitol R that starts off the RegEx string - I figured out that it lets you use the single escape characters, but I couldn't find it documented anywhere...?
Thanks to all and best regards!
Scott
-
@MScottM said in QRegularExpressionMatch:
I wanted to ask about the capitol R that starts off the RegEx string - I figured out that it lets you use the single escape characters, but I couldn't find it documented anywhere...?