It is currently March 28th, 2024, 11:33 am

Can I exclude specific letters from a variable?

Get help with creating, editing & fixing problems with skins
Post Reply
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Can I exclude specific letters from a variable?

Post by kyriakos876 »

Here is what I want to do:

Code: Select all

[MeterButton1]
Meter=Button
ButtonImage=....
ButtonCommand=[!SetVariable X "#CurrentSection#"][!Update]
This will return a Variable X as X=MeterButton1

I want to exclude somehow the strings "MeterButton" and store the remaining strings in another variable Y. So the Y variable would become Y=1.
Is there a way to do that?

Note: I know I can set the name of the section as 1,2,3... but this will work if you have only one set of meters (also it can cause trouble in some other occasions). If I have for example Button1 and Text1, I can't set both meter as 1, as this will display only the first meter parsed.

As always,
thanks in advance!
Last edited by kyriakos876 on April 21st, 2017, 5:03 pm, edited 1 time in total.
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Can I exclude specific letters from a variable?

Post by jsmorley »

I'm sure there is some convoluted way with a String measure and RegExpSubstitute, but ... ick.

What I would do is make use of the oft' overlooked capability of the Script measure to execute ANY Lua command or multiple command;command sequence without needing anything at all in the .lua script file. It's basically just a way to command-line execute any valid Lua from a bang.

If you need multiple commands, just separate them with semi-colons ;. Do be careful about quoting. In particular I strongly recommend using single quotes ' for quoting strings in Lua, rather than fighting with Rainmeter about double quotes ".

So first, you do need a .lua script file. However, it can be just an empty shell.

Test.Lua:

Code: Select all

function Initialize()
end

function Update()
end
Then you can use that to execute Lua commands from your bang.

Test.ini:

Code: Select all

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

[MeasureLua]
Measure=Script
ScriptFile=#CURRENTPATH#Test.lua
UpdateDivider=-1

[MeterButton1]
Meter=Button
ButtonImage=#@#Buttons\ComputerButton.png
ButtonCommand=[!SetVariable X "#CurrentSection#"][!CommandMeasure MeasureLua "SKIN:Bang('!SetVariable', 'Y', string.sub('#CURRENTSECTION#',-1))"][!Update]
Voila, an easy to use substring function that can be used anywhere you can execute a bang...

https://docs.rainmeter.net/manual/lua-scripting/
http://lua-users.org/wiki/StringLibraryTutorial
string.sub(s, i [, j])

Return a substring of the string passed. The substring starts at i. If the third argument j is not given, the substring will end at the end of the string. If the third argument is given, the substring ends at and includes j.

> = string.sub("Hello Lua user", 7) -- from character 7 including 7 until the end
Lua user
> = string.sub("Hello Lua user", 7, 9) -- from character 7 until and including 9
Lua
> = string.sub("Hello Lua user", -8) -- 8 from the end until the end
Lua user
> = string.sub("Hello Lua user", -8, 9) -- 8 from the end until 9 from the start
Lua
> = string.sub("Hello Lua user", -8, -6) -- 8 from the end until 6 from the end
Lua
1.png
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Re: Can I exclude specific letters from a variable?

Post by kyriakos876 »

jsmorley wrote:I'm sure there is some convoluted way with a String measure and RegExpSubstitute, but ... ick.
Yes, I wanted to do something similar to what you did with the .lua above but I don't know how to exclude strings from a variable with RegExp. I mean, in your example you simply added the whole variable (In this case #CURRENTSECTION# ) and you excluded the number you wanted with - (In this case -1 ) I just have limited knowledge of RegExp I don't know what is the syntax in RegExp to exclude a string from a variable. In .lua it was a simple - in reg exp is...?

Your example is simple and it covered me but if you could, for the shake of knowledge, answer me the above, I'd be grateful!
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Can I exclude specific letters from a variable?

Post by jsmorley »

Code: Select all

[MeasureString]
Measure=String
String=MyNumberIs1
RegExpSubstitute=1
Substitute=".*(.)$":"\1"
The Substitute is just saying "skip any character . any number of times * and then capture () the last character . before the end of the string $". Then just replace the entire string with the first \1 capture. The value of [MeasureString] will be "1".

I mean, that is how you would get the last character of a string with regular expression. Nothing to do with "variables" as such, and the process to replace a variable with the last character of another variable is just too ugly to think about really. It's too many steps, and would have to be done for every variable you wanted to treat that way. Like I said, ick...
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Re: Can I exclude specific letters from a variable?

Post by kyriakos876 »

jsmorley wrote:

Code: Select all

[MeasureString]
Measure=String
String=MyNumberIs1
RegExpSubstitute=1
Substitute=".*(.)$":"\1"
I'm not sure but I think there is a syntax like {1-9} or something like that, that excludes all the numbers. I can add this to "\1" and have only one measure. Do you happen to know the syntax? Should look something like:
Substitute=".*(.)$":"\{1-9}".
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Can I exclude specific letters from a variable?

Post by jsmorley »

kyriakos876 wrote:I'm not sure but I think there is a syntax like {1-9} or something like that, that excludes all the numbers. I can add this to "\1" and have only one measure. Do you happen to know the syntax? Should look something like:
Substitute=".*(.)$":"\{1-9}".
Substitute="(?U).*(\d+)$":"\1"

So you specify a \d (numeric digit), and + (1 or more).

You don't really need the specific curly brace {} quantifier, although it will work. That is generally used for something that isn't handled by the normal quantifier symbols * (0 or more) + (1 or more) ? (0 or 1), like "exactly 2" or "between 2 and 5". In the later case you might use \d{2,5}.

So \d+ and \d{1,} are the same thing. Why waste three of your valuable supply of characters if you don't have to? You will be sorry when you run out and have to buy a new keyboa

Note that regular expression is by default "greedy", and in the case of:

String=MyNumberIs12
Substitute=".*(\d+)$":"\1"

This is "greedy" and will return just "2" It will consume all characters until the "last point" that the match is true.

String=MyNumberIs12
Substitute="(?U).*(\d+)$":"\1"

This is "Ungreedy", and will return "12", which is what you want. It will consume all characters until the "first point" that the match is true.

https://docs.rainmeter.net/manual/skins/option-types/#Resources
https://www.debuggex.com/cheatsheet/regex/pcre
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Re: Can I exclude specific letters from a variable?

Post by kyriakos876 »

jsmorley wrote: String=MyNumberIs12
Substitute="(?U).*(\d+)$":"\1"
I understood everything (or at least I think I did) except for one thing. In the Substitute="(?U).*(\d+)$":"\1" what does the "\1" stand for? I mean in the previous example it stands for the number I want to match, but in this example we use (\d+) which means one or more numbers, so why do we need the "\1" if it matches all the numbers anyway ? I check the links your provided yet I didn't get that part.
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Can I exclude specific letters from a variable?

Post by jsmorley »

kyriakos876 wrote:I understood everything (or at least I think I did) except for one thing. In the Substitute="(?U).*(\d+)$":"\1" what does the "\1" stand for? I mean in the previous example it stands for the number I want to match, but in this example we use (\d+) which means one or more numbers, so why do we need the "\1" if it matches all the numbers anyway ? I check the links your provided yet I didn't get that part.
You have what \1 means completely wrong...

A Substitute consists of the following components:

Substitute="text to search for":"replacement text"

In the case of a regular expression Substitute, where you have RegExpSubstitute=1 on the measure, you are generally going to be using that to (capture) some part of the string. The tokens \1 \2 \3... etc. are used in the right hand side, the "replacement text" to indicate that you want to use the value from one or more of the (captures) that are on the left hand side.

String=OneTwoThreeFour
RegExpSubstitute=1
Substitute="One(.*)Three(.*)":"\1 comes between One and Three, which is before \2"

Produces "Two comes between One and Three, which is before Four"

So those numbered tokens are just a reference to the captures. They are almost identical to "StringIndex" on a WebParser measure.

So in our example above:

String=MyNumberIs12
Substitute="(?U).*(\d+)$":"\1"

You are (capturing) one or more numeric digits on the left hand side with (\d+). Then you are replacing the entire string with the value of the first \1 capture from the left hand side, or in this case the value "12".
User avatar
kyriakos876
Posts: 919
Joined: January 30th, 2017, 2:01 am
Location: Greece

Re: Can I exclude specific letters from a variable?

Post by kyriakos876 »

jsmorley wrote:You have what \1 means completely wrong...

A Substitute consists of the following components:

Substitute="text to search for":"replacement text"
Oh... that explains a lot... lol I went instantly into the syntax characters and never took the time to read what I'm actually doing there...
jsmorley wrote:
In the case of a regular expression Substitute, where you have RegExpSubstitute=1 on the measure, you are generally going to be using that to (capture) some part of the string. The tokens \1 \2 \3... etc. are used in the right hand side, the "replacement text" to indicate that you want to use the value from one or more of the (captures) that are on the left hand side.

String=OneTwoThreeFour
RegExpSubstitute=1
Substitute="One(.*)Three(.*)":"\1 comes between One and Three, which is before \2"

Produces "Two comes between One and Three, which is before Four"

So those numbered tokens are just a reference to the captures. They are almost identical to "StringIndex" on a WebParser measure.
Yea, now I think I'm covered. Thanks!
User avatar
jsmorley
Developer
Posts: 22628
Joined: April 19th, 2009, 11:02 pm
Location: Fort Hunt, Virginia, USA

Re: Can I exclude specific letters from a variable?

Post by jsmorley »

Glad to help.
Post Reply