It is currently April 18th, 2024, 10:35 am

RegExp and IfMatch proper use

Get help with creating, editing & fixing problems with skins
User avatar
alexandeu
Posts: 52
Joined: March 15th, 2013, 1:22 am
Location: Canada

RegExp and IfMatch proper use

Post by alexandeu »

Hi,
I've run into a problem while parsing from weather.codes.
The way the data shows makes it tricky to parse the correct weather code as they show:
[Weather Code]:[City, Country]
[CAXX0485]:[Surrey, Canada]

WebParser doesn't parse the code before the matching text and catching the first instance of code from
the search does not work because there are cities with the same name but from different countries.

I decided to try a workaround but unsure why it doesn't seem to work.

Basically, I am using one measure parsing all the "City, Country"s from the 2nd column
and using another measure to parse the weather codes, hoping to find a row that matches the exact "City, Country", and applying that row number to the "StringIndex" of a measure to output the correct weather code.

Code: Select all

[Rainmeter]
Author=Ekojain
Update=1000

[Metadata]
Version=1.0

[Variables]
City=Kyoto
Country=Japan
Location=
NameString=

;MEASURE (As the "Weather Codes" website has weather code first and city, country after,
;the two measures will parse the first 4 "City, Country"s and the first 4 Weather codes
 [MeasureWeatherName]
 Measure=Plugin
 Plugin=WebParser
 URL=https://weather.codes/search/?q=#City#
 RegExp=(?siU)<dd>(.*)</dd>.*<dd>(.*)</dd>.*<dd>(.*)</dd>.*<dd>(.*)</dd>.*
 UpdateRate=-1
 FinishAction=
 DynamicVariables=1
 [MeasureWeatherCode]
 Measure=Plugin
 Plugin=WebParser
 URL=https://weather.codes/search/?q=#City#
 RegExp=(?siU)<dt>(.*)</dt>.*<dt>(.*)</dt>.*<dt>(.*)</dt>.*<dt>(.*)</dt>.*
 UpdateRate=-1
 FinishAction=
 DynamicVariables=1

;Depending on the index line that the correct City, Country text matches,
;the correct index line will be named as "#NameString#" for [MeasureCode] to output.
 [MeasureName1]
 Measure=Plugin
 Plugin=WebParser
 URL=[MeasureWeatherName]
 StringIndex=1
 [CalcName1]
 Measure=Calc
 Formula=[MeasureName1]
 IfMatch=#City#, #Country#:True
 IfMatchAction=[!WriteKeyValue "MeasureCode" "StringIndex" "1" "Weather.ini"]

 [MeasureName2]
 Measure=Plugin
 Plugin=WebParser
 URL=[MeasureWeatherName]
 StringIndex=2
 [CalcName2]
 Measure=Calc
 Formula=[MeasureName2]
 IfMatch=#City#, #Country#:True
 IfMatchAction=[!WriteKeyValue "MeasureCode" "StringIndex" "2" "Weather.ini"]

 [MeasureName3]
 Measure=Plugin
 Plugin=WebParser
 URL=[MeasureWeatherName]
 StringIndex=3
 [CalcName3]
 Measure=Calc
 Formula=[MeasureName3]
 IfMatch=#City#, #Country#:True
 IfMatchAction=[!WriteKeyValue "MeasureCode" "StringIndex" "3" "Weather.ini"]

 [MeasureName4]
 Measure=Plugin
 Plugin=WebParser
 URL=[MeasureWeatherName]
 StringIndex=4
 [CalcName4]
 Measure=Calc
 Formula=[MeasureName4]
 IfMatch=#City#, #Country#:True
 IfMatchAction=[!WriteKeyValue "MeasureCode" "StringIndex" "4" "Weather.ini"]

;This reads the output from [MeasureWeatherCode] and applies the right Stringindex to display.
 [MeasureCode]
 Measure=Plugin
 Plugin=WebParser
 URL=[MeasureWeatherCode]
 StringIndex=#NameString#
 UpdateRate=-1
 DynamicVariables=1

;This is just the trigger for the input.
 [MeterBACK]
 Meter=Image
 X=0
 Y=0
 W=200
 H=100
 SolidColor=FFFFFF

 [CountryBack]
 Meter=String
 X=10
 Y=10
 Text=Country
 FontSize=10
 FontColor=000000
 FontFace=Myriad Pro
 AntiAlias=1
 [CoutryBacktext]
 Meter=String
 Y=r
 X=100r
 FontSize=10
 FontColor=000000
 FontFace=Myriad Pro
 Text=#Country#
 LeftMouseUpAction=[!CommandMeasure "INPUT1 ExecuteBatch 1-2"]
 AntiAlias=1

 [CityBack]
 Meter=String
 X=10
 Y=30r
 Text=City
 FontSize=10
 FontColor=000000
 FontFace=Myriad Pro
 AntiAlias=1
 [CityBacktext]
 Meter=String
 Y=r
 X=100r
 FontSize=10
 FontColor=000000
 FontFace=Myriad Pro
 Text=#City#
 LeftMouseUpAction=[!CommandMeasure "INPUT2 ExecuteBatch 1-2"]
 AntiAlias=1

 [CodeBack]
 Meter=String
 X=10
 Y=30r
 Text=Location
 FontSize=10
 FontColor=000000
 FontFace=Myriad Pro
 AntiAlias=1
 [CodeBacktext]
 Meter=String
 Y=r
 X=100r
 FontSize=10
 FontColor=000000
 FontFace=Myriad Pro
 Text=#Location#
 AntiAlias=1

;This input writes the output from [MeasureCode], which is the Weather Code to the Variables file.
 [INPUT1]
 Measure=Plugin
 Plugin=InputText.dll
 X=80
 Y=10
 W=100
 H=16
 SolidColor=100,100,100,255
 FontColor=0,0,0,255
 FontSize=10
 FontFace=Arial
 StringAlign=Right
 FocusDismiss=1
 Command1=[!WriteKeyValue "Variables" "Country" "$UserInput$" "Weather.ini"]
 Command2=[!WriteKeyValue "Variables" "Location" "[MeasureCode]" "Weather.ini"][!Refresh]

 [INPUT2]
 Measure=Plugin
 Plugin=InputText.dll
 X=80
 Y=40
 W=100
 H=16
 SolidColor=100,100,100,255
 FontColor=0,0,0,255
 FontSize=10
 FontFace=Arial
 StringAlign=Right
 FocusDismiss=1
 Command1=[!WriteKeyValue "Variables" "City" "$UserInput$" "Weather.ini"]
 Command2=[!WriteKeyValue "Variables" "Location" "[MeasureCode]" "Weather.ini"][!Refresh]

I can only assume I am using the IfMatch option wrong. Any help or criticism is welcome.
User avatar
balala
Rainmeter Sage
Posts: 16143
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: RegExp and IfMatch proper use

Post by balala »

There are more problems with your code:
  • The posted RegExp doesn't work for me, so I finally rewrote it.
  • A Calc measure works ONLY with numerical values. Strings are not allowed.
  • On the IfMatch option, the :true expression is not needed. In fact, you have to remove it, otherwise the option won't work.
  • The IfMatch / IfMatchAction option pairs can be applied directly to the WebParser measure, there's no need at all to add suplimentare measures, useless complicating the code.
I'm not very sure I understood how would you get the !WriteKeyValue bangs to work in the IfMatchAction options, the posted workaround, at least for me, looks to be very complicated. I'd rather show the found city names, along with the appropriate weather codes, then let the user to click the desired city name. With this click, the code should be written as a variable. But let's not go ahead too quickly.
So, here is my rewritten code, please give it a try and let me know how does it work. I also rewrote the string meter.
Here is the code:

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1

[Metadata]
Version=1.0
Author=Ekojain

[Variables]
@include=#@#Variables.inc
@include2=#@#Language\#LINGUA#.inc
NameString=
Item=(?(?=.*<dt).*>(.*)</dt><dd>(.*), (.*)</dd>)

;MEASURE (As the "Weather Codes" website has weather code first and city, country after,
;the two measures will parse the first 4 "City, Country"s and the first 4 Weather codes
 
[MeasureWeatherName]
Measure=Plugin
Plugin=WebParser
URL=https://weather.codes/search/?q=#City#
RegExp=(?siU)(?(?=.*<dl>).*<dt>(.*)</dt><dd>(.*), (.*)</dd>)#Item##Item##Item##Item#
;RegExp=(?siU)<dd>(.*)</dd>.*<dd>(.*)</dd>.*<dd>(.*)</dd>.*<dd>(.*)</dd>.*
;UpdateRate=-1
FinishAction=
DynamicVariables=1

[MeasureWeatherCode1]
Measure=Plugin
Plugin=WebParser
URL=[MeasureWeatherName]
StringIndex=1

[MeasureName1]
Measure=Plugin
Plugin=WebParser
URL=[MeasureWeatherName]
StringIndex=2
;IfMatch=#City#, #Country#
;IfMatchAction=[!WriteKeyValue "MeasureCode" "StringIndex" "1" "#CURRENTCONFIG#"]

[MeasureWeatherCode2]
Measure=Plugin
Plugin=WebParser
URL=[MeasureWeatherName]
StringIndex=4

[MeasureName2]
Measure=Plugin
Plugin=WebParser
URL=[MeasureWeatherName]
StringIndex=5
;IfMatch=#City#, #Country#
;IfMatchAction=[!WriteKeyValue "MeasureCode" "StringIndex" "2" "#CURRENTCONFIG#"]

[MeasureWeatherCode3]
Measure=Plugin
Plugin=WebParser
URL=[MeasureWeatherName]
StringIndex=7

[MeasureName3]
Measure=Plugin
Plugin=WebParser
URL=[MeasureWeatherName]
StringIndex=8
;IfMatch=#City#, #Country#
;IfMatchAction=[!WriteKeyValue "MeasureCode" "StringIndex" "3" "#CURRENTCONFIG#"]

[MeasureWeatherCode4]
Measure=Plugin
Plugin=WebParser
URL=[MeasureWeatherName]
StringIndex=10

[MeasureName4]
Measure=Plugin
Plugin=WebParser
URL=[MeasureWeatherName]
StringIndex=11
;IfMatch=#City#, #Country#
;IfMatchAction=[!WriteKeyValue "MeasureCode" "StringIndex" "4" "#CURRENTCONFIG#"]

;This reads the output from [MeasureWeatherCode] and applies the right Stringindex to display.
[MeasureCode]
Measure=Plugin
Plugin=WebParser
URL=[MeasureWeatherName]
StringIndex=#NameString#
UpdateRate=-1
DynamicVariables=1

;This is just the trigger for the input.
[CityBack]
Meter=String
MeterStyle=Label
Y=(#InputY#+#Row#*2)
Text=#txtcity#

[CityBacktext]
Meter=String
MeterStyle=TextStyle
Text=#City#
StringCase=Upper
LeftMouseUpAction=[!CommandMeasure "INPUT4 ExecuteBatch 1-2"]
AntiAlias=1

;This input writes the output from [MeasureCode], which is the Weather Code to the Variables file.
[INPUT4]
Measure=Plugin
Plugin=InputText.dll
X=#ColInputX#
Y=(#InputY#+#Row#*2)
W=#InputW#
H=16
SolidColor=100,100,100,255
FontColor=0,0,0,255
FontSize=10
FontFace=Arial
StringAlign=Right
FocusDismiss=1
Command1=!WriteKeyValue "Variables" "City" "$UserInput$" "#@#Variables.inc"
Command2=[!Refresh Stealthy\Climate Climate-L.ini][!Refresh Stealthy\Climate Climate-R.ini][!WriteKeyValue "Variables" "Location" "[MeasureCode]" "#@#Variables.inc"][!Refresh]

[Uptime]
MeasureName=MeasureName1
MeasureName2=MeasureWeatherCode1
MeasureName3=MeasureName2
MeasureName4=MeasureWeatherCode2
MeasureName5=MeasureName3
MeasureName6=MeasureWeatherCode3
MeasureName7=MeasureName4
MeasureName8=MeasureWeatherCode4
Meter=STRING
X=0
Y=0
Padding=15,5,15,5
FontColor=220,220,220
SolidColor=0,0,0,150
FontSize=8
FontFace=Segoe UI
StringStyle=BOLD
StringAlign=LEFT
AntiAlias=1
Text=1.: %1 (%2)#CRLF#2.: %3 (%4)#CRLF#3.: %5 (%6)#CRLF#4.: %7 (%8)
This code uses Lookahead Assertion, so it'll return so many citys (up to four, but this can be easily extended), as many exist.
If this does work well, we'll rewrite the string meters, to make each line clickable, as I said above. Note that although this is not a too great mistake, the Author options now belongs to the [Metadata] section, not to [Rainmeter], as it did a while ago. I moved it there.
User avatar
alexandeu
Posts: 52
Joined: March 15th, 2013, 1:22 am
Location: Canada

Re: RegExp and IfMatch proper use

Post by alexandeu »

Hey much appreciated for the help!

Unfortunately I can't parse anything with your regexp or mine, leaving me very confused :confused:

Code: Select all

[Rainmeter]
Update=100

[Metadata]
Version=1.0
Author=Ekojain

[Variables]
City=Vancouver
Item1=(?(?=.*<dl>).*<dt>(.*)</dt>)
Item2=(?(?=.*<dl>).*<dd>(.*)</dd>)
Location=

 
;[MeasureWeatherName]
;Measure=Plugin
;Plugin=WebParser
;URL=https://weather.codes/search/?q=#City#
;RegExp=(?siU)<dt>(.*)</dt>.*<dd>(.*)</dd>.*<dt>(.*)</dt>.*<dd>(.*)</dd>.*<dt>(.*)</dt>.*<dd>(.*)</dd>.*<dt>(.*)</dt>.*<dd>(.*)</dd>.*
;RegExp=(?siU)<dd>(.*)</dd>.*<dd>(.*)</dd>.*<dd>(.*)</dd>.*<dd>(.*)</dd>.*
;RegExp=(?(?=.*<dt).*>(.*)</dt><dd>(.*), (.*)</dd>)
;UpdateRate=-1
;DynamicVariables=1

 [MeasureWeatherName]
 Measure=Plugin
 Plugin=WebParser
 URL=https://weather.codes/search/?q=#City#
 RegExp=(?siU)#Item2##Item2##Item2##Item2#
 UpdateRate=-1
 FinishAction=[!UpdateMeasureGroup "MN" "Weather.ini"]
 [MeasureWeatherCode]
 Measure=Plugin
 Plugin=WebParser
 URL=https://weather.codes/search/?q=#City#
 RegExp=(?siU)#Item##Item##Item##Item#
 UpdateRate=-1
 FinishAction=[!UpdateMeasureGroup "MC" "Weather.ini"]

;Measures
 [MeasureWeatherCode1]
 Measure=Plugin
 Plugin=WebParser
 URL=[MeasureWeatherCode]
 StringIndex=1
 Group=MC
 [MeasureName1]
 Measure=Plugin
 Plugin=WebParser
 URL=[MeasureWeatherName]
 StringIndex=1
 Group=MN
 
 [MeasureWeatherCode2]
 Measure=Plugin
 Plugin=WebParser
 URL=[MeasureWeatherCode]
 StringIndex=2
 Group=MC
 [MeasureName2]
 Measure=Plugin
 Plugin=WebParser
 URL=[MeasureWeatherName]
 StringIndex=2
 Group=MN
 
 [MeasureWeatherCode3]
 Measure=Plugin
 Plugin=WebParser
 URL=[MeasureWeatherCode]
 StringIndex=3
 Group=MC
 [MeasureName3]
 Measure=Plugin
 Plugin=WebParser
 URL=[MeasureWeatherName]
 StringIndex=3
 Group=MN
 
 [MeasureWeatherCode4]
 Measure=Plugin
 Plugin=WebParser
 URL=[MeasureWeatherCode]
 StringIndex=4
 Group=MC
 [MeasureName4]
 Measure=Plugin
 Plugin=WebParser
 URL=[MeasureWeatherName]
 StringIndex=4
 Group=MN

;This is just the trigger for the input.
 [CityBack]
 Meter=String
 X=0
 Y=0
 W=100
 H=30
 SolidColor=0,0,0,150
 Text=City
 FontSize=10
 FontColor=dddddd
 FontFace=Myriad Pro
 AntiAlias=1
 [CityBacktext]
 Meter=String
 X=200r
 Y=r
 W=100
 H=30
 SolidColor=0,0,0,150
 FontSize=10
 FontColor=dddddd
 FontFace=Myriad Pro
 StringAlign=Right
 Text=#City#
 LeftMouseUpAction=[!CommandMeasure "INPUT2 ExecuteBatch 1-2"]
 AntiAlias=1

;This input writes the output from [MeasureCode], which is the Weather Code to the Variables file.
 [INPUT2]
 Measure=Plugin
 Plugin=InputText.dll
 X=100
 Y=0
 W=100
 H=30
 SolidColor=100,100,100,255
 FontColor=0,0,0,255
 FontSize=10
 FontFace=Arial
 StringAlign=Right
 FocusDismiss=1
 Command1=[!WriteKeyValue "Variables" "City" "$UserInput$" "Weather.ini"]
 Command2=[!Refresh]

[Uptime]
MeasureName=MeasureName1
MeasureName2=MeasureWeatherCode1
MeasureName3=MeasureName2
MeasureName4=MeasureWeatherCode2
MeasureName5=MeasureName3
MeasureName6=MeasureWeatherCode3
MeasureName7=MeasureName4
MeasureName8=MeasureWeatherCode4
Meter=STRING
X=0
Y=30
Padding=15,5,15,5
FontColor=220,220,220
SolidColor=0,0,0,150
FontSize=8
FontFace=Segoe UI
StringStyle=BOLD
StringAlign=LEFT
AntiAlias=1
Text=1.: %1 (%2)#CRLF#2.: %3 (%4)#CRLF#3.: %5 (%6)#CRLF#4.: %7 (%8)
I have some experience with parsing but obviously not enough. Everything looks fine to me but ... frustrating. :(
I wonder if I'm just overlooking something really simple
User avatar
alexandeu
Posts: 52
Joined: March 15th, 2013, 1:22 am
Location: Canada

Re: RegExp and IfMatch proper use

Post by alexandeu »

OH!! Something happened and it works now! No change to the latest edit of the code lol :D

Thanks for the help! Hope to repay the favour!
User avatar
CyberTheWorm
Posts: 860
Joined: August 22nd, 2016, 11:32 pm
Location: Surrey, B.C., Canada

Re: RegExp and IfMatch proper use

Post by CyberTheWorm »

try replacing your code with this

Code: Select all

[Variables]
City=Vancouver
Item1=.*<dt>(.*)</dt>
Item2=.*<dd>(.*)</dd>

[MeasureWeatherCode]
 Measure=Plugin
 Plugin=WebParser
 URL=https://weather.codes/search/?q=#City#
 RegExp=(?siU)#Item1##Item1##Item1##Item1#

The only source of knowledge is experience. Albert Einstein
Deviant Art Page
User avatar
balala
Rainmeter Sage
Posts: 16143
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: RegExp and IfMatch proper use

Post by balala »

alexandeu wrote:OH!! Something happened and it works now! No change to the latest edit of the code lol :D
Here is what probably happened: https://forum.rainmeter.net/viewtopic.php?p=136507#p136507
That's a common behavior of the WebParser plugin. Don't be surprised when you can't get it to properly work and anything isn't parsed, instead, restart Rainmeter (not just reload the skin!).