It is currently February 26th, 2020, 10:17 am

Regexp again (i hope you not bored with this question)

Help with creating, editing & fixing problems with skins
User avatar
LittleOne
Posts: 48
Joined: March 24th, 2015, 4:03 am

Regexp again (i hope you not bored with this question)

Post by LittleOne »

Code: Select all

{
 "items": [
  {
   "summary": "Test 1",
   "start": {
    "date": "2020-02-09"
   }
  },
  {
   "summary": "Test 2",
   "start": {
    "date": "2020-02-11"
   }
  },
  {
   "summary": "Test 3",
   "start": {
    "date": "2020-02-17"
   }
  }
 ]
}
how to capture Test 2 value from the summary with date 2020-02-11

note:
  • that the number of fields can be changed dynamically
  • summary or date value can be anything not necessary Test 2 or 2020-02-11
User avatar
grovkillen
Posts: 6
Joined: February 5th, 2020, 5:06 pm

Re: Regexp again (i hope you not bored with this question)

Post by grovkillen »

May I suggest buying a license for RegExBuddy? I have and it's money well spent.

https://www.regexbuddy.com
User avatar
LittleOne
Posts: 48
Joined: March 24th, 2015, 4:03 am

Re: Regexp again (i hope you not bored with this question)

Post by LittleOne »

grovkillen wrote:
February 7th, 2020, 6:17 am
May I suggest buying a license for RegExBuddy? I have and it's money well spent.

https://www.regexbuddy.com
No, because there is a free online regex tools that i use, even with it i can not solve this problem.
Yincognito
Posts: 818
Joined: February 27th, 2015, 2:38 pm

Re: Regexp again (i hope you not bored with this question)

Post by Yincognito »

Don't worry, it can be done. I'm on mobile now and can't build a suitable regex properly, but will come back later with a solution (in case you don't get one by then).

In the meantime, you can investigate setting your regex anchors to },{ and capture the middle item. If you need the 2nd one, you'd have to count its predecessors, and just capture the item that comes after.

P.S. Note that in more complex scenarios that involve arbitrary opening and closing parenthesis, you need recursion to balance them, hence my unanswered question about it on the forum.
User avatar
grovkillen
Posts: 6
Joined: February 5th, 2020, 5:06 pm

Re: Regexp again (i hope you not bored with this question)

Post by grovkillen »

LittleOne wrote:
February 7th, 2020, 7:14 am
No, because there is a free online regex tools that i use, even with it i can not solve this problem.
Free as in better? ;) I have tried them and I find that RegExBuddy guides me to success. But you can keep on asking here and others will solve it for you.

Tried something like this?

Code: Select all

(?<="summary": ")\p{Any}*?(?=",)

Code: Select all

(?<="date": ")[\d\-]{10}
User avatar
balala
Rainmeter Sage
Posts: 9781
Joined: October 11th, 2010, 6:27 pm
Location: Gheorgheni, Romania

Re: Regexp again (i hope you not bored with this question)

Post by balala »

LittleOne wrote:
February 7th, 2020, 5:10 am
how to capture Test 2 value from the summary with date 2020-02-11

note:
  • that the number of fields can be changed dynamically
  • summary or date value can be anything not necessary Test 2 or 2020-02-11
Something like this?

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1

[Variables]
Var=1

[MeasureRainmeter]
Measure=WebParser
UpdateRate=870
URL=file://#@#MyFile.txt
RegExp=(?siU)"summary": "Test #Var#",.*"start":.*"date": "(.*)"
DynamicVariables=1

[MeasureDate]
Measure=WebParser
Url=[MeasureRainmeter]
StringIndex=1

[MeterString]
Meter=STRING
MeasureName=MeasureDate
X=0
Y=0
Padding=15,5,15,5
FontColor=220,220,220
FontEffectColor=0,0,0
StringEffect=Shadow
SolidColor=0,0,0,150
FontSize=8
FontFace=Segoe UI
StringStyle=BOLD
StringAlign=LEFT
AntiAlias=1
Text=%1
DynamicVariables=1
LeftMouseUpAction=[!SetVariable Var "((#Var#<=2)?(#Var#+1):1)"][!UpdateMeasure "MeasureRainmeter"][!CommandMeasure "MeasureRainmeter" "Update"][!UpdateMeter "MeterString"]
User avatar
LittleOne
Posts: 48
Joined: March 24th, 2015, 4:03 am

Re: Regexp again (i hope you not bored with this question)

Post by LittleOne »

balala wrote:
February 7th, 2020, 8:26 am
Something like this?
Sorry that`s not it, because it depend on the word "Test", what i need is to get the value after "summary": " since its not always "Test"

maybe its simpler to say that it is calendar event and its always changed i need to get the summary value for every single Date Value its not always have 3 event only it can be just one or whatever number exist, the length of summary value is not always same

more like something like this

Code: Select all

(?siU)summary": "(.*)".*2020-02-11
but this regex will get the Test 1 instead of Test 2
Yincognito
Posts: 818
Joined: February 27th, 2015, 2:38 pm

Re: Regexp again (i hope you not bored with this question)

Post by Yincognito »

LittleOne wrote:
February 7th, 2020, 9:46 am
[...]what i need is to get the value after "summary": " since its not always "Test"

maybe its simpler to say that it is calendar event and its always changed i need to get the summary value for every single Date Value its not always have 3 event only it can be just one or whatever number exist, the length of summary value is not always same
As promised, I came back with a solution, after getting home.

Now I'm assuming you have no spaces, tab or new line characters (i.e. \s*) in your string, as what you presented might have been formatted this way for clarity. In this case, for the unspaced string:

Code: Select all

{"items":[{"summary":"Test 1","start":{"date":"2020-02-09"}},{"summary":"Test 2","start":{"date":"2020-02-11"}},{"summary":"Test 3","start":{"date":"2020-02-17"}}]}
, this regex will do the trick, by capturing the desired summary and date in \1 and \2:

Code: Select all

(?siU)\{"items":\[\{(?:.*\}(?:,\{|\])){0,1}+"summary":"(.*)","start":\{"date":"(.*)"\}.*\}(?:,\{|\])
In case you do have spaces, tab or new line characters in your string, just use \s* where needed:

Code: Select all

(?siU)\{\s*"items":\s*\[\s*\{(?:.*\}(?:,\s*\{|\s*\])){0,1}+\s*"summary":\s*"(.*)",\s*"start":\s*\{\s*"date":\s*"(.*)"\s*\}.*\}(?:,\s*\{|\s*\])
The above regex works by counting the predecessors of the item where you actually capture, so if you need data from the 1st item you have {0,0}+ in the regex, if you need the 2nd you have {0,1}+, if you need the 3rd you have {0,2}+ and so on. Basically you only have to modify a single number to "jump" to a different item. If you want, you can store that number in a variable in Rainmeter, and assuming you work with string (the WebParser case is more problematic since a dynamic StringIndex option requires updating the parent measure) measures and have DynamicVariables=1 in the right places, you'll be able to control which item you need data from.

As I said, you should be careful with the problem of balancing arbitrary paranthesis, choosing your anchors (the boundaries of your patterns) wisely. Since there's no solution for that other than regex recursion, and recursion is not compatible with Rainmeter as far as I tested, you are out of luck if you don't know where the most relevant parathesis occur in your string.

P.S. The above was tested in regexr.com, and this method of getting the n-th item in a "list" has been extensively used in my skins for years, so it's reliable.
User avatar
LittleOne
Posts: 48
Joined: March 24th, 2015, 4:03 am

Re: Regexp again (i hope you not bored with this question)

Post by LittleOne »

@Yincognito that`s pretty neat regex trick you have there, but unfortunately i can not implement on the skin i work on, its pretty hard for me to explain this on english since its not my language, so i attach the skin file

i make some dummy event on Google Calendar at feb - (2, 8, 12, 16)
what i want to have is the summary on that specific date as tooltips on the marked date
the marker triggered by webparser regexp error/success

every measure start with _ (exp: [_D1] )and every meter end with _ (exp: [D2_] ) the regex needed is start on [_D1] Measure at line 282, im not making any child measure yet to capture the summary because of the problem, the fonts used is "open sans" you can download it for free at https://fonts.google.com/

sorry if i make some weird sentence
You do not have the required permissions to view the files attached to this post.
Yincognito
Posts: 818
Joined: February 27th, 2015, 2:38 pm

Re: Regexp again (i hope you not bored with this question)

Post by Yincognito »

LittleOne wrote:
February 7th, 2020, 1:12 pm
@Yincognito that`s pretty neat regex trick you have there, but unfortunately i can not implement on the skin i work on, its pretty hard for me to explain this on english since its not my language, so i attach the skin file

i make some dummy event on Google Calendar at feb - (2, 8, 12, 16)
what i want to have is the summary on that specific date as tooltips on the marked date
the marker triggered by webparser regexp error/success

every measure start with _ (exp: [_D1] )and every meter end with _ (exp: [D2_] ) the regex needed is start on [_D1] Measure at line 282, im not making any child measure yet to capture the summary because of the problem, the fonts used is "open sans" you can download it for free at https://fonts.google.com/

sorry if i make some weird sentence
That's no problem that English is not your main language - it's not mine either, so no worries. The problem is that you're asking me to modify that skin for you - which I won't. :D I never used Google Calendar (and I won't start now) and the skin is quite complex - understanding and modifying that takes some time and effort that I'm not willing to waste on it.

What I will do though is present you with a basic working skin that works. It parses the WebParserDump.txt you included in your upload (such a file is downloaded by the original skin every time it runs, probably for debugging purposes), and gets the desired summary and date. The WebParserDump.txt file must be placed in the same folder as the skin whose code is below (I, for example, created an Analog Calendar folder in Rainmeter's regular skin folder - c:\Users\[username]\Documents\Rainmeter\Skins - where I copied the Analog Calendar.ini containing the code below and the WebParserDump.txt file):

Code: Select all

[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
BackgroundMode=2
SolidColor=0,0,0,255

---Measures---

[MeasureAnalogCalendar]
Measure=WebParser
URL=file://#CURRENTPATH#WebParserDump.txt
RegExp=(?siU)\{\s*"items":\s*\[\s*\{(?:.*\}(?:,\s*\{|\s*\])){0,1}+\s*"summary":\s*"(.*)",\s*"start":\s*\{\s*"date":\s*"(.*)"\s*\}.*\}(?:,\s*\{|\s*\])

[MeasureSummary]
Measure=WebParser
URL=[MeasureAnalogCalendar]
StringIndex=1

[MeasureDate]
Measure=WebParser
URL=[MeasureAnalogCalendar]
StringIndex=2

---Meters---

[MeterSummary]
Meter=String
Y=0R
MeasureName=MeasureSummary
FontSize=14
FontColor=222,255,227,255
StringStyle=Bold
AntiAlias=1

[MeterRSSItemTitle]
Meter=String
MeasureName=MeasureDate
Y=0R
FontSize=14
FontColor=222,255,227,255
StringStyle=Bold
AntiAlias=1
To make this work on the actual Google Calendar all you should have to do is replace the file://#CURRENTPATH#WebParserDump.txt string from [MeasureAnalogCalendar]'s URL option with the real address of the Google Calendar page where you navigate. As for integrating changes in the original skin, you'd have to do it on your own - no offense. ;-)