It is currently June 24th, 2024, 1:09 am

Mlb Live Scores

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

Re: Mlb Live Scores

Post by Yincognito »

jake2456 wrote: September 6th, 2023, 2:08 am Ive got a small bug im trying to work out but im not sure how to fix it.

Im using this:

Code: Select all

(?(?=.*"num":6,.*"home".*"runs":.*,.*"away".*"runs":.*,).*"num":6,.*"home".*"runs":(.*),.*"away".*"runs":(.*),)
To Capture this:

Code: Select all

{"num":6,"ordinalNum":"6th","home":{"runs":0,"hits":0,"errors":0,"leftOnBase":0},"away":{"runs":0,"hits":2,"errors":0,"leftOnBase":0}}]
But the "runs":0, section doesnt always exist for that inning until either a run is scored or the inning is over and they add another inning("num":7 section)
For example:

Code: Select all

{"num":6,"ordinalNum":"6th","home":{"hits":0,"errors":0,"leftOnBase":0},"away":{"runs":1,"hits":2,"errors":0,"leftOnBase":1}}],"teams":{"home":{"runs":1,"hits":3,"errors":0,"leftOnBase":3},"away":{"runs":1,"hits":8,"errors":0,"leftOnBase":7}},
So in turn it jumps ahead to the next instance:

Code: Select all

"teams":{"home":{"runs":1,"hits":3,"errors":0,"leftOnBase":3},"away":{"runs":1,"hits":8,"errors":0,"leftOnBase":7}},
which always exists and captures that instead those giving the wrong values.

Ive tryd a few different ways. Even thought i had it solved with this:

Code: Select all

(?(?=.*"num":6,"ordinalNum":".*","home":{"runs":.*,).*"num":6,"ordinalNum":".*","home":{"runs":(.*),)(?(?=.*"num":6,"ordinalNum":".*","home":{"runs":.*,"hits":.*,"errors":.*,"leftOnBase":.*},"away":{"runs":.*,).*"num":6,"ordinalNum":".*","home":{"runs":.*,"hits":.*,"errors":.*,"leftOnBase":.*},"away":{"runs":(.*),)
But for some reason this never captures a value for the away runs even if they exist.
I'm on my phone now so I can't test, but it's a situation that occurs often in these type of patterns.

The solution for the condition should be simple, just an "OR aka | non capturing group" like (?:runs:.*,|) which is basically equivalent to an optional like (?:runs:.*,)?? where the second ? inverts the (?U) ungreedy initial flag back to greedy again to match the longer possible content first and make sure it's retrieved if it exists.

In the actual match part though, the solution is slightly complicated by the fact that you capture there, but even so, a "branch reset group" where the two alternative groups share the same group number should to the trick, like (?|runs:(.*),|()) where the second part, if it occurs, will have the same StringIndex but will capture the empty string.

By the way, if you don't like having nothing there you can replace the empty part in both the non capturing group and the branch reset one with .* since the flag is set to ungreedy anyway and * will match as few characters as possible aka zero.

See regexr.com where you set the regex flavor to the PCRE used by Rainmeter from the top right combo box and check Regex Reference > Groups & References sidebar to the left of the page.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
jake2456
Posts: 87
Joined: June 8th, 2015, 10:39 pm

Re: Mlb Live Scores

Post by jake2456 »

Well i tryed a few different ways to implement what you said(not sure if i did it correctly) and was able to get one try to work on regexr correctly but when i input that into rainmeter it failed. So if you get a chance to take a look at it id appreciate it. if you go to https://www.mlb.com/scores see whos currently playing and then go into the skin top right corner theres a circle to click and select team.
User avatar
Yincognito
Rainmeter Sage
Posts: 7492
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Mlb Live Scores

Post by Yincognito »

jake2456 wrote: September 6th, 2023, 7:07 pm Well i tryed a few different ways to implement what you said(not sure if i did it correctly) and was able to get one try to work on regexr correctly but when i input that into rainmeter it failed. So if you get a chance to take a look at it id appreciate it. if you go to https://www.mlb.com/scores see whos currently playing and then go into the skin top right corner theres a circle to click and select team.
Alright, I found a suitable test case and saved it offline, I'll take a look at it sometimes tomorrow.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
User avatar
Yincognito
Rainmeter Sage
Posts: 7492
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Mlb Live Scores

Post by Yincognito »

jake2456 wrote: September 6th, 2023, 7:07 pm Well i tryed a few different ways to implement what you said(not sure if i did it correctly) and was able to get one try to work on regexr correctly but when i input that into rainmeter it failed. So if you get a chance to take a look at it id appreciate it. if you go to https://www.mlb.com/scores see whos currently playing and then go into the skin top right corner theres a circle to click and select team.
Keeping the , out from the groups and using something similar to:

Code: Select all

(?(?=.*"num":4,.*"home".*(?:"runs":.*|),.*"away".*"runs":.*,).*"num":4,.*"home".*(?|"runs":(.*)|()),.*"away".*"runs":(.*),)
seems to work for me when testing the JSON inside this ZIP (the changes to the Disabled and URL options are for testing purpose only; note that to avoid potential surprises, reserved regex characters like bracket literals should be escaped by preceding them with a backslash, e.g. \{ instead of plain { and so on)...

...\MLBScoreboard2023\@Resources\Pages\live - original.json:
live - original.zip
...\MLBScoreboard2023\@Resources\Measures.inc:

Code: Select all

[MeasureGame1]
...
Disabled=0
URL=file://#@#Pages\live - original.json
RegExp=(?siU)"time":"(.*)","ampm":"(.*)".*"detailedState":"(.*)",.*"allStarStatus":"N","id":(.*),.*"teamName":"(.*)","locationName":"(.*)",.*"wins":(.*),"losses":(.*),.*"allStarStatus":"N","id":(.*),.*"teamName":"(.*)","locationName":"(.*)",.*"wins":(.*),"losses":(.*),(?(?=.*"probablePitchers":{"away":{"id":.*,"fullName":".*","link":".*"},"home":{"id":.*,"fullName":".*",).*"probablePitchers":{"away":{"id":(.*),"fullName":"(.*)","link":".*"},"home":{"id":(.*),"fullName":"(.*)",)(?(?=.*"linescore":{"currentInning":.*,"currentInningOrdinal":".*","inningState":".*",).*"linescore":{"currentInning":(.*),"currentInningOrdinal":".*","inningState":"(.*)",)(?(?=.*"innings".*"num":1,.*"home".*(?:"runs":.*|),.*"away".*"runs":.*,).*"innings".*"num":1,.*"home".*(?|"runs":(.*)|()),.*"away".*"runs":(.*),)(?(?=.*"num":2,.*"home".*(?:"runs":.*|),.*"away".*"runs":.*,).*"num":2,.*"home".*(?|"runs":(.*)|()),.*"away".*"runs":(.*),)(?(?=.*"num":3,.*"home".*(?:"runs":.*|),.*"away".*"runs":.*,).*"num":3,.*"home".*(?|"runs":(.*)|()),.*"away".*"runs":(.*),)(?(?=.*"num":4,.*"home".*(?:"runs":.*|),.*"away".*"runs":.*,).*"num":4,.*"home".*(?|"runs":(.*)|()),.*"away".*"runs":(.*),)(?(?=.*"num":5,.*"home".*(?:"runs":.*|),.*"away".*"runs":.*,).*"num":5,.*"home".*(?|"runs":(.*)|()),.*"away".*"runs":(.*),)(?(?=.*"num":6,.*"home".*(?:"runs":.*|),.*"away".*"runs":.*,).*"num":6,.*"home".*(?|"runs":(.*)|()),.*"away".*"runs":(.*),)(?(?=.*"num":7,.*"home".*(?:"runs":.*|),.*"away".*"runs":.*,).*"num":7,.*"home".*(?|"runs":(.*)|()),.*"away".*"runs":(.*),)(?(?=.*"num":8,.*"home".*(?:"runs":.*|),.*"away".*"runs":.*,).*"num":8,.*"home".*(?|"runs":(.*)|()),.*"away".*"runs":(.*),)(?(?=.*"num":9,.*"home".*(?:"runs":.*|),.*"away".*"runs":.*,).*"num":9,.*"home".*(?|"runs":(.*)|()),.*"away".*"runs":(.*),)(?(?=.*"num":10,.*"home".*(?:"runs":.*|),.*"away".*"runs":.*,).*"num":10,.*"home".*(?|"runs":(.*)|()),.*"away".*"runs":(.*),)(?(?=.*"teams":{"home":{"runs":.*,"hits":.*,"errors":.*,"leftOnBase":.*},"away":{"runs":.*,"hits":.*,"errors":.*,"leftOnBase":.*}},).*"teams":{"home":{"runs":(.*),"hits":(.*),"errors":(.*),"leftOnBase":.*},"away":{"runs":(.*),"hits":(.*),"errors":(.*),"leftOnBase":.*}},)(?(?=.*"defense":{"pitcher":{"id":.*,"fullName":".*",).*"defense":{"pitcher":{"id":(.*),"fullName":"(.*)",)(?(?=.*"offense":{"batter":{"id":.*,"fullName":".*",).*"offense":{"batter":{"id":(.*),"fullName":"(.*)",)(?(?=.*"link":".*"}},"balls":.*,"strikes":.*,"outs":.*},).*"link":".*"}},"balls":(.*),"strikes":(.*),"outs":(.*)},)(?(?=.*"winner":{"id":.*,"fullName":".*",).*"winner":{"id":(.*),"fullName":"(.*)",)(?(?=.*"loser":{"id":.*,"fullName":".*",).*"loser":{"id":(.*),"fullName":"(.*)",)(?(?=.*"save":{"id":.*,"fullName":".*",).*"save":{"id":(.*),"fullName":"(.*)",)
...


Another way to approach this in Rainmeter would be to store partial patterns in variables, break up larger captures into smaller ones, and use StringIndex2 as well, for example (simplified to innings only, for better clarity):

Code: Select all

[Variables]
@include=#@#Variables.inc
InningNo=(?(?=.*\{"num":\d+,.*\}\}).*(\{"num":\d+,.*\}\}))
HomeRuns=(?siU)"home":\{"runs":(.*),
AwayRuns=(?siU)"away":\{"runs":(.*),

[Rainmeter]
Update=1000

...

[MeasureGame1]
...
RegExp=(?siU)"innings":\[#InningNo##InningNo##InningNo##InningNo##InningNo##InningNo##InningNo##InningNo##InningNo##InningNo#\]
...

[MeasureHomeRuns4]
Measure=WebParser
Url=[MeasureGame#Game#]
StringIndex=4
RegExp=#HomeRuns#
StringIndex2=1
DynamicVariables=1

[MeasureAwayRuns4]
Measure=WebParser
Url=[MeasureGame#Game#]
StringIndex=4
RegExp=#AwayRuns#
StringIndex2=1
DynamicVariables=1
This way, there's no possibility for runs from a certain "num" to be accounted for another "num", since each "num" part is extracted via StringIndex, while whatever subparts of it are extracted via StringIndex2. If the approach is used for the entire pattern, the advantage is that it's easier and shorter to change specific parts of the whole pattern and see the modifications applied everywhere, while the disadvantage is that it's harder to reconstruct the entire pattern from all the smaller bits if you want to test it someplace else.
You do not have the required permissions to view the files attached to this post.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
jake2456
Posts: 87
Joined: June 8th, 2015, 10:39 pm

Re: Mlb Live Scores

Post by jake2456 »

Thanks, ill give it a try later tonight and let you know.

Def nice seeing a real use example there. It looks like i wasnt to far off on a few of my attempts.
User avatar
Yincognito
Rainmeter Sage
Posts: 7492
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Mlb Live Scores

Post by Yincognito »

jake2456 wrote: September 7th, 2023, 6:29 pm Thanks, ill give it a try later tonight and let you know.

Def nice seeing a real use example there. It looks like i wasnt to far off on a few of my attempts.
Sure thing. ;-)
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
jake2456
Posts: 87
Joined: June 8th, 2015, 10:39 pm

Re: Mlb Live Scores

Post by jake2456 »

I am still seeing an issue where if an inning away runs dont exist yet it goes and grabs teams home runs.

Id assume doing the same for each innings away runs would work too?

Code: Select all

(?(?=.*"num":1,.*"home".*(?:"runs":.*|),.*"away".*(?:"runs":.*|),).*"num":1,.*"home".*(?|"runs":(.*)|()),.*"away".*(?|"runs":(.*)|()),)
User avatar
Yincognito
Rainmeter Sage
Posts: 7492
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Mlb Live Scores

Post by Yincognito »

jake2456 wrote: September 8th, 2023, 1:31 am I am still seeing an issue where if an inning away runs dont exist yet it goes and grabs teams home runs.

Id assume doing the same for each innings away runs would work too?

Code: Select all

(?(?=.*"num":1,.*"home".*(?:"runs":.*|),.*"away".*(?:"runs":.*|),).*"num":1,.*"home".*(?|"runs":(.*)|()),.*"away".*(?|"runs":(.*)|()),)
The pattern looks correct, so yeah, it should, assuming there's no , between "home" or "away" and "runs" or its replacement. The .* after the former should match whatever replacement of "runs" and its value if that doesn't exist, and the commas left outside after the brackets should make sure that things don't match stuff from other following parts that might contain "runs" (because the flag for the pattern is set to ?U aka ungreedy, making the preceding * match as few characters as possible, in effect forcing the , to match its first occurrence).

Of course, if they one day change the order and "runs" along with its value (or their replacement, now "hits" from what I've seen) are not the first field after "home" or "away", then that will break the pattern as it is, requiring inserting additional ,.* as needed before the brackets. If the position fluctuates significantly, then no similar approach will work and you'll have to resort to the safer StringIndex2 alternative detailed above.
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth
jake2456
Posts: 87
Joined: June 8th, 2015, 10:39 pm

Re: Mlb Live Scores

Post by jake2456 »

Ok thanks. Yea hopefully they dont change anything for awhile.
User avatar
Yincognito
Rainmeter Sage
Posts: 7492
Joined: February 27th, 2015, 2:38 pm
Location: Terra Yincognita

Re: Mlb Live Scores

Post by Yincognito »

jake2456 wrote: September 8th, 2023, 6:12 pm Ok thanks. Yea hopefully they dont change anything for awhile.
Indeed, that's a bit less likely to happen in a JSON presumably used as data source by multiple parties (compared to the more frequent changes in a webpage HTML).
Profiles: Rainmeter ProfileDeviantArt ProfileSuites: MYiniMeterSkins: Earth