It is currently April 20th, 2024, 4:53 am

Regex discrepancy in similar measures

Get help with creating, editing & fixing problems with skins
User avatar
Yincognito
Rainmeter Sage
Posts: 7128
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Regex discrepancy in similar measures

Post by Yincognito »

So, I have this little trick that I use in my skins to get the N-th element out of a list-like string. It's something that helped me a lot in making my skins dynamic in terms of data return. However, while trying to apply the same again using 2 different methods (either by parsing in [MeasureTestOne] or by chopping the string of unneeded parts in [MeasureTestTwo]), I get different results, although it's only the method that is different and not the regex approach:

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1

[Variables]
TestString="{a},{b},{c},{d},{e},{{f1,f2}},{g},{h},{i},{j},{k},{l},{m},{n},{o}"
Element=0

[MeasureCounter]
Group=TestsGroup
Measure=Calc
Formula=0
UpdateDivider=-1
OnUpdateAction=[!SetVariable Element [MeasureCounter]]

[MeasureTestOne]
Group=TestsGroup
Measure=String
String="#TestString#"
UpdateDivider=-1
RegExpSubstitute=1
Substitute="(?siU)^\{(?:.*\}(?:,\{|$)){0,#Element#}+(.*)(?:\},\{.*|\})$":"\1"
DynamicVariables=1

[MeasureTestTwo]
Group=TestsGroup
Measure=String
String="#TestString#"
UpdateDivider=-1
RegExpSubstitute=1
Substitute="(?siU)^\{(?:.*\}(?:,\{|$)){0,#Element#}+":"","(?:\},\{.*|\})$":""
DynamicVariables=1

[MeterTests]
Meter=String
Y=0R
FontSize=20
FontWeight=500
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
MeasureName=MeasureTestOne
MeasureName2=MeasureTestTwo
Text="T. String = #TestString##CRLF#Element = #Element##CRLF#Result 1 = %1#CRLF#Result 2 = %2"
MouseScrollUpAction=[!SetOption MeasureCounter Formula ((MeasureCounter<=(0))?(15):(MeasureCounter-1))][!UpdateMeasureGroup "TestsGroup"][!UpdateMeter *][!Redraw]
MouseScrollDownAction=[!SetOption MeasureCounter Formula ((MeasureCounter>=(15))?(0):(MeasureCounter+1))][!UpdateMeasureGroup "TestsGroup"][!UpdateMeter *][!Redraw]
DynamicVariables=1
As you can see by scrolling you mouse wheel, it all goes well in returning the N-th letter/string from between the curled brackets, with the exception of the 5th element (indexing begins at 0), which in [MeasureTestOne] correctly returns it as {f1,f2}, while [MeasureTestTwo] incorrectly gets me k. I've tested the same thing at regexr.com and regex101.com and they return the same correct string {f1,f2} irrespective of method (parse or substitution). What's up with that?!

Obviously, I would prefer [MeasureTestTwo] to work as expected, since in case of out-of-bounds indexes (like 15), it promptly returns the empty string. Where could the problem be?
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Yincognito
Rainmeter Sage
Posts: 7128
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Regex discrepancy in similar measures

Post by Yincognito »

Figured out what was wrong with it. According to the Rainmeter's manual, with RegExpSubstitute, a (capture) may not return an empty string. Care should be taken when using * (zero or more) quantifiers or (?(?= (If/Then) lookahead tests, as a capture must either cause the entire regular expression to "fail", or return a value of some kind.

In other words, if I modify the replacements in [MeasureTestTwo] from "" to, say "-", it will work (bar the unneeded "-" present in the results). This is strange, however, since no capture group is used (unless you count the unused \0 as a capture, that is). Yes, there are quantifiers, but no actual capture at all. Can't see why the previous attempt failed, unless the manual forgot to mention that the behavior happens even when there is no (capture) being taken from the pattern.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth