Code: Select all
Substitute="#SearchString#":"~","[^~]":"","~":"9"
Substitute="#SearchString#":"~","[^~]":"","~":"+1"
Maybe there should be a perfect solution, but I don't reach.
BTW, to say again, I love the Lua way without no such problem.
Code: Select all
Substitute="#SearchString#":"~","[^~]":"","~":"9"
Substitute="#SearchString#":"~","[^~]":"","~":"+1"
Here is your perfect solution, based on the string length code balala mentioned earlier (if you have other places where you need perfection or folks label it impossible, just call me, I can't resist those challenges, LOL).mak_kawa wrote: ↑July 12th, 2020, 3:00 am Now maybe I almost figured out the problem using "two-stage" substitution, but not perfect (see below).As you see, this substitution doesn't work if the target string contains "~" character. It seems to be a rare case so ignorable, really??Code: Select all
Substitute="#SearchString#":"~","[^~]":"","~":"9" Substitute="#SearchString#":"~","[^~]":"","~":"+1"
Maybe there should be a perfect solution, but I don't reach.
BTW, to say again, I love the Lua way without no such problem.
Code: Select all
[Variables]
; String to search into
SearchInto="Hello, world#CRLF#The world is a big place.#CRLF#World Wonders are great places to visit."
; String to search for (never use the empty string, i.e. "", here!)
SearchFor="o"
; Whether or not the search should be case sensitive ("i" = case insensitive, "" = case sensitive)
MatchCase=""
[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
BackgroundMode=2
SolidColor=47,47,47,255
---Measures---
[MeasureNumberOfOccurencesString]
Measure=String
String=#SearchInto#
UpdateDivider=-1
RegExpSubstitute=1
Substitute="(?s#MatchCase#U).*#SearchFor#":"#SearchFor#","(?s#MatchCase#)^((?:#SearchFor#)*).*$":"\1","(?s#MatchCase#)(?:^\\\d+|\\\d+$)":"","(?s#MatchCase#)#SearchFor#":"+1"
DynamicVariables=1
[MeasureNumberOfOccurencesCalc]
Measure=Calc
Formula=[MeasureNumberOfOccurencesString]
DynamicVariables=1
---Meters---
[MeterNumberOfOccurences]
Meter=STRING
FontFace=Consolas
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
FontSize=9
AntiAlias=1
ClipString=2
ClipStringW=300
MeasureName=MeasureNumberOfOccurencesCalc
Text="Search For:#CRLF#'#SearchFor#'#CRLF##CRLF#Search Into:#CRLF#'#SearchInto#'#CRLF##CRLF#Occurences =#CRLF#%1"
DynamicVariables=1
Code: Select all
Substitute="(?U).*o":"o","^((?:o)*).*$":"\1","(?:^\\\d+|\\\d+$)":"","o":"+1"
Haha, no need to - even though I wouldn't mind the moniker, one has to be humble enough in his quest for perfection (which does exist) and making the "impossible" be possible. It's all about our minds' ability to get better, no big deal, and it's in everyone's reach.
Code: Select all
[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
[Variables]
SearchInto=Hello, world#CRLF#The "world" is a 'big' place.#CRLF#World Wonders are great places to visit.
SearchFor=o
---Measures---
[Lua]
Measure=Script
ScriptFile=Test.lua
Disabled=1
---Meters---
[MeterNumberOfOccurences]
Meter=String
FontFace=Consolas
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
FontSize=9
AntiAlias=1
ClipString=2
ClipStringW=300
Text=There are [&Lua:Count('#SearchInto#','#SearchFor#')] intances of "#SearchFor#" in the string "#SearchInto#"
DynamicVariables=1
Code: Select all
function Count(stringArg, searchArg)
stringArg = string.lower(stringArg)
searchArg = string.lower(searchArg)
tempString, instanceCount = string.gsub(stringArg, searchArg, '')
return instanceCount
end
Code: Select all
SearchInto=^^^^Hello World^^^^
SearchFor=^
Code: Select all
SearchInto=^^^^Hello World^^^^
SearchFor=%^
Code: Select all
[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
[Variables]
SearchInto=Four score and seven years ago our fathers brought forth on this continent, a new nation, conceived in liberty, and dedicated to the proposition that all men are created equal.#CRLF##CRLF#Now we are engaged in a great civil war, testing whether that nation, or any nation so conceived and so dedicated, can long endure. We are met on a great battlefield of that war. We have come to dedicate a portion of that field, as a final resting place for those who here gave their lives that that nation might live. It is altogether fitting and proper that we should do this.#CRLF##CRLF#But in a larger sense, we cannot dedicate, we cannot consecrate, we cannot hallow, this ground. The brave men, living and dead, who struggled here, have consecrated it, far above our poor power to add or detract. The world will little note, nor long remember, what we say here, but it can never forget what they did here. It is for us the living, rather, to be dedicated here to the unfinished work which they who fought here have thus far so nobly advanced. It is rather for us to be here dedicated to the great task remaining before us - that from these honored dead we take increased devotion to that cause for which they gave the last full measure of devotion - that we here highly resolve that these dead shall not have died in vain - that this nation, under God, shall have a new birth of freedom - and that government of the people, by the people, for the people, shall not perish from the earth.
SearchFor=[\x20]we[\x20]
---Measures---
[Lua]
Measure=Script
ScriptFile=Test.lua
Disabled=1
---Meters---
[MeterNumberOfOccurences]
Meter=String
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
FontSize=11
AntiAlias=1
ClipString=2
ClipStringW=320
InlineSetting=Weight | 700
InlinePattern=(?i)^There are (.*) instances.*$
InlineSetting2=Color | 132,255,135,255
InlinePattern2=(?i)^There are (.*) instances.*$
InlineSetting3=Weight | 700
InlinePattern3=(?i)(#SearchFor#)
InlineSetting4=Color | 154,187,255,255
InlinePattern4=(?i)(#SearchFor#)
Text=There are [&Lua:Count('#SearchInto#','#SearchFor#')] instances of "#SearchFor#" in the string#CRLF##CRLF#"#SearchInto#"
DynamicVariables=1
All of Lua is very, very efficient, as it is a language that I like to think of as "close to the metal", just two steps removed from machine language. It is entirely written in vanilla C language, and has almost no "bloat" at all. As to string.gsub() specifically, in all due fairness to Yincognito, string.gsub() is almost a perfect functional equivalent to RegExpSubstitute / Substitute in Rainmeter. Both have the same purpose. Both do a "global search and replace" on a string. The advantage to string.gsub() in this specific case is that it has the native ability to return the answer to "how many times did I do that?" as a part of the function. It's what makes it just falling-down easy to use for "counting" how many times a character or word or phrase appears in a string.mak_kawa wrote: ↑July 13th, 2020, 1:01 am Hi jsmorley
"string.gsub"... new to me. If I can handle this function, the "for do" loop is unnecessary anymore. It might be more smart...
So, I tried it and works. I am not sure about its performance advantage or so, but thanks a lot for cool professional input.
Yeah, I refrained from replying on your previous posts, as I didn't want to go on and start another inflamatory debate over the abilities and strengths of Regex in bare Rainmeter code and Lua. I actually don't mind such debates, as I think I'm well prepared with arguments in every situation, but doing this again and again is probably not going to be pleasant for the discussion partner. It turns out I was right to do that, since you said pretty much what I would have said (though probably more to the point) if I would have posted my reply. One small note though, I completely disagree with you labeling (yet again, LOL) one of my code samples as "hugely complicated" - I mean that was just 12 lines of code for 2 measures, and just 4 comma separated substitutions in a single option; if that was "complicated", what about your code / substitutions / RegExp options in the Weather.com megaskin (just an example)?jsmorley wrote: ↑July 13th, 2020, 2:09 am All of Lua is very, very efficient, as it is a language that I like to think of as "close to the metal", just two steps removed from machine language. It is entirely written in vanilla C language, and has almost no "bloat" at all. As to string.gsub() specifically, in all due fairness to Yincognito, string.gsub() is almost a perfect functional equivalent to RegExpSubstitute / Substitute in Rainmeter. Both have the same purpose. Both do a "global search and replace" on a string. The advantage to string.gsub() in this specific case is that it has the native ability to return the answer to "how many times did I do that?" as a part of the function. It's what makes it just falling-down easy to use for "counting" how many times a character or word or phrase appears in a string.
Other than that, it has no particular advantage over Substitute in Rainmeter, and I generally wouldn't jump out to Lua just to extract or replace a string. Once again in all fairness, Substitute with PCRE regular expression is in fact a more powerful tool than Pattern Matching in Lua.
Over time, we have tried to make it more and more possible to stay in native Rainmeter code, in instances where perhaps Lua was the only practical solution in the past. Examples of this are IfCondition, IfMatch, and InlineSetting/InlinePattern.
Generally, I lean toward Lua when what I am trying to do is very "procedural" in nature, for / next, do / while, if/then/elseif/then/else/then and such, as Rainmeter is not a procedural programming language, or when I find a need for using "arrays", what Lua calls "tables". Lua has capabilities in those areas that just can't reasonably be replicated in Rainmeter code. I also tend to glance Lua's way when something "repetitive" needs to be done. If I have 100 strings that all need to have "cat" replaced with "dog" in them, I'm not going to be fond of having 100 identical RegExpSubstitute / Substitute options. I'm going to be tempted to write ONE string.gsub() in a function in Lua, and just call it 100 times with Inline Lua, right in the meters where I want to use them.
Code: Select all
[Lua]
Measure=Script
ScriptFile=MyLua.lua
Disabled=1