I want to show digits string with "3 digits separator", for example, "12345678" to "12,345,678".
It is probably easy with RegExp substitution only when the length of the digits is known and fixed. That is, in the cae of above digits, Substitute="^(\d{1,3})(\d{3})(\d{3})$":"\1,\2,\3" does work.
But when the length of the digits is unknown and variable?? What substitute expression I should use commonly for such digits as "12" "12345" "123456789"??
Lookahead assertion? Or something? In any case, it is far beyond of my novice RegExp skill. Any help is appreciated.
Or, as always, am I missing something easy?...
It is currently April 24th, 2024, 12:43 am
Digits separator
-
- Posts: 908
- Joined: December 30th, 2015, 9:47 am
-
- Developer
- Posts: 22629
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
Re: Digits separator
Code: Select all
[Rainmeter]
Update=1000
DynamicWindowSize=1
AccurateText=1
[Variables]
Separator=","
Decimal="."
[MeasureNumber]
Measure=Calc
Formula=10000000.99
RegExpSubstitute=1
Substitute="^(\d+)$":"\1A","([\.,])":"A","\d{1,3}(?=(\d{3})+A)":"\0B","A$":"","B":"#Separator#","A":"#Decimal#"
[MeterNumber]
Meter=String
FontSize=11
FontWeight=400
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
DynamicVariables=1
Text=Formatted: [MeasureNumber]#CRLF#Unformatted: [MeasureNumber:2]
https://forum.rainmeter.net/viewtopic.php?f=5&t=16551#p92235
You do not have the required permissions to view the files attached to this post.
-
- Posts: 908
- Joined: December 30th, 2015, 9:47 am
Re: Digits separator
Hi jsmorley
Thank you for...great and brilliant substitution. It does work perfectly. Awesome!!
But sadly in fact, I almost can't understand this substitution expression. ("NanigaNandaka" in Japanese) It is desperately necessary for me to learn regular expression much more...
Thank you for...great and brilliant substitution. It does work perfectly. Awesome!!
But sadly in fact, I almost can't understand this substitution expression. ("NanigaNandaka" in Japanese) It is desperately necessary for me to learn regular expression much more...
-
- Developer
- Posts: 22629
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
Re: Digits separator
Fear not, I don't understand it either...mak_kawa wrote: ↑November 27th, 2019, 1:56 pm Hi jsmorley
Thank you for...great and brilliant substitution. It does work perfectly. Awesome!!
But sadly in fact, I almost can't understand this substitution expression. ("NanigaNandaka" in Japanese) It is desperately necessary for me to learn regular expression much more...
-
- Developer
- Posts: 22629
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
Re: Digits separator
It actually isn't perfect, as it will have trouble with negative numbers. I think this is really pushing the boundaries of what I would use Substitute for. Hang on a second, and I will demonstrate a Lua function that I prefer to do this.
-
- Developer
- Posts: 22629
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
Re: Digits separator
I would use something like this:
Skin:
FormatNumber.lua:
This will handle a number of any size and any number of decimal places, and both positive and negative numbers. It will optionally allow the decimal and separator characters to be defined. Another advantage is that it can be used anywhere you want to display a number, without needing that complicated Substitute on each and every measure returning a number value. The Lua is certainly more involved than the Substitute, but only needs to be created once, and used anywhere.
I will note that C++ has some trouble with very large floating point numbers (numbers with decimal places), in that the decimal portion of the number value will have a small rounding error. This means that a number like 12345678.1 will internally return a value like 12345678.099999996 or something. That is why we want to pass the number value to the Lua script as a 'string' and not a number, then use Lua to convert this to a number as needed to evaluate if it is positive or not, then back to a string to tear it apart. It's also why we use [MeasureName] instead of [MeasureName:] to display the unformatted number in the meter.
Search keys: comma separated formatted numbers
Skin:
Code: Select all
[Rainmeter]
Update=1000
AccurateText=1
DynamicWindowSize=1
[Variables]
[Lua]
Measure=Script
ScriptFile=FormatNumber.lua
SepChar=,
DecChar=.
Disabled=1
[MeasureNumber]
Measure=String
String=12345678.1
[MeterBigNumber]
Meter=String
FontSize=13
FontColor=255,255,255,255
SolidColor=47,47,47,255
Padding=5,5,5,5
AntiAlias=1
Text=Unformatted : [MeasureNumber]#CRLF#Formatted : [&Lua:FormatNumber('[&MeasureNumber]')]
DynamicVariables=1
Code: Select all
function FormatNumber(inNum)
sepChar = SELF:GetOption('SepChar', ',')
decChar = SELF:GetOption('DecChar', '.')
negNum = nil
outNum = inNum
if tonumber(outNum) < 0 then
negNum = 1
outNum = tostring(math.abs(outNum))
end
replaceCount = 0
outNum = outNum:gsub('^(.-)%D(.-)$', '%1'..decChar..'%2')
while true do
outNum, replaceCount = outNum:gsub('^(-?%d+)(%d%d%d)', '%1'..sepChar..'%2')
if (replaceCount == 0) then
break
end
end
if negNum then
return '-'..outNum
else
return outNum
end
end
This will handle a number of any size and any number of decimal places, and both positive and negative numbers. It will optionally allow the decimal and separator characters to be defined. Another advantage is that it can be used anywhere you want to display a number, without needing that complicated Substitute on each and every measure returning a number value. The Lua is certainly more involved than the Substitute, but only needs to be created once, and used anywhere.
I will note that C++ has some trouble with very large floating point numbers (numbers with decimal places), in that the decimal portion of the number value will have a small rounding error. This means that a number like 12345678.1 will internally return a value like 12345678.099999996 or something. That is why we want to pass the number value to the Lua script as a 'string' and not a number, then use Lua to convert this to a number as needed to evaluate if it is positive or not, then back to a string to tear it apart. It's also why we use [MeasureName] instead of [MeasureName:] to display the unformatted number in the meter.
Search keys: comma separated formatted numbers
You do not have the required permissions to view the files attached to this post.
-
- Posts: 908
- Joined: December 30th, 2015, 9:47 am
Re: Digits separator
Hi jsmorley
This smart Lua script works perfectly. Thanks.
Anyway, the RegExp string is a kind of magic spell causing me some headache.
This smart Lua script works perfectly. Thanks.
Anyway, the RegExp string is a kind of magic spell causing me some headache.
-
- Posts: 134
- Joined: June 30th, 2014, 8:44 am
Re: Digits separator
Code: Select all
[tester]
Measure = String
String = 12389234857983271584971234
RegExpSubstitute = 1
Substitute = "(\d)(?=(\d{3})+$)" : "\1,"
If your numbers have decimals, then you'd use this regex instead:
Code: Select all
Substitute = "(\d)(?=(\d{3})+\.)" : "\1,"
The regex is fairly simple, but I'll give you a basic walkthrough of what's happening anyway.
First we capture a digit. Then we use a positive lookahead to see if groups of 3 digits continually repeat (at least once) until they naturally reach the end of the string (or a decimal place if you're using that one). If the positive lookahead returns true, we capture the digit in question and replace it with itself followed by a comma.
Make sense?
To make it handle both decimal places and not having decimal places would be a fair bit more complicated but it could still be done just lemme know.
I know you have a lua solution already but I just don't think lua's worth it for such a simple task, personally.
-
- Developer
- Posts: 22629
- Joined: April 19th, 2009, 11:02 pm
- Location: Fort Hunt, Virginia, USA
Re: Digits separator
To each his own certainly. Personally, I'm not afraid of Lua, and find it to be very powerful and very easy to use. In my view, the advantage to the Lua approach here is that it can be used on as many numbers as you like / need in the skin, without having to replicate a fairly complicated RegExpSubstitute on each measure returning a number you might want to display.
With a calculated number, I resist that you likely will "know" if the number is going to end up with a fractional amount or not...
But if we all liked the same things, there would be a hell of a traffic jam.
With a calculated number, I resist that you likely will "know" if the number is going to end up with a fractional amount or not...
But if we all liked the same things, there would be a hell of a traffic jam.
-
- Posts: 134
- Joined: June 30th, 2014, 8:44 am
Re: Digits separator
That's why I want MeasureStyles!jsmorley wrote: ↑November 27th, 2019, 11:21 pm To each his own certainly. Personally, I'm not afraid of Lua, and find it to be very powerful and very easy to use. In my view, the advantage to the Lua approach here is that it can be used on as many numbers as you like / need in the skin, without having to replicate a fairly complicated RegExpSubstitute on each measure returning a number you might want to display.
But if we all liked the same things, there would be a hell of a traffic jam.