RegEx to trim floating decimal places Topic is solved

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
carno
Posts: 265
Joined: 20 Jun 2014, 16:48

Re: RegEx to trim floating decimal places

29 Jan 2019, 14:49

Xtra wrote:
29 Jan 2019, 14:46

Code: Select all

TrimZeros(n) {
    len := StrLen(n)
    Loop, 4
    {
        if (SubStr(n, len, 1) = 0)
            --len
        else
            break
    }
    return SubStr(n, 1, len)
}
Always assumes 6 digits after the decimal per OP
I apologize, and yes, my original assumption was only 6 decimal places.
carno
Posts: 265
Joined: 20 Jun 2014, 16:48

Re: RegEx to trim floating decimal places

29 Jan 2019, 14:51

Xtra wrote:
29 Jan 2019, 14:46

Code: Select all

TrimZeros(n) {
    len := StrLen(n)
    Loop, 4
    {
        if (SubStr(n, len, 1) = 0)
            --len
        else
            break
    }
    return SubStr(n, 1, len)
}
Always assumes 6 digits after the decimal per OP
I apologize, and yes, my original assumption was only 6 decimal places. :facepalm:
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: RegEx to trim floating decimal places

29 Jan 2019, 15:17

For better responses, provide a fuller list of before/after examples.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
SOTE
Posts: 1426
Joined: 15 Jun 2015, 06:21

Re: RegEx to trim floating decimal places

29 Jan 2019, 15:32

carno wrote:
29 Jan 2019, 14:47
SOTE wrote:
29 Jan 2019, 14:33
Am I missing something or misunderstanding the question? Because this seems to work.

Code: Select all

List =
(
123.000000
123.012345
123.100000
123.123456
123.120000
)
msgbox % list

Loop, Parse, list, `n
{
	If InStr(A_Loopfield, "0000")
	{
	result .=  StrReplace(A_Loopfield, "0000", "") "`n"
	}
	else
	{
	result .=  A_Loopfield "`n"
	}
}
msgbox % result
Looks like a bit inconsistent with these numbers: :think:
123.456700 > 123.456700
123.4567000000 > 123.456700
123.4567000000000000 > 123.4567
Per the OP, 6 digits after the decimal. However, I did see another case that will throw a monkey wrench, which would be .000012

However, you could do the below. To make it deal with more numbers after the decimal, you could move the starting position from SubStr over or calculate the length after the decimal and then move the starting position over. So to always make sure the A_Loopfield is the correct one to cut zeros from, you do a calculation after 2 spots to the right of the decimal, and make sure you get zero. Then it won't matter how many digits, as long as it adds up to zero.

Code: Select all

List =
(
123.000000
123.012345
123.100000
123.123456
123.120000
123.000012
)
msgbox % list

Loop, Parse, list, `n
{
	X := SubStr(A_Loopfield, 7, 4)
	If X = 0
	{
	result .=  StrReplace(A_Loopfield, "0000", "") "`n"
	}
	else
	{
	result .=  A_Loopfield "`n"
	}
}
msgbox % result
Last edited by SOTE on 29 Jan 2019, 15:38, edited 2 times in total.
carno
Posts: 265
Joined: 20 Jun 2014, 16:48

Re: RegEx to trim floating decimal places

29 Jan 2019, 15:33

jeeswg wrote:
29 Jan 2019, 15:17
For better responses, provide a fuller list of before/after examples.
I first apologize. The assumption in my original request was 6 decimal places ONLY! :oops:
That said, I ran the following: :ugeek:

Code: Select all

vList := "
(
123.000000
123.012345
123.100000
123.123456
123.120000
0.000814
0.0000814
0.00000814
0.000000814
0.0000000814
123.456700
123.4567000000
123.4567000000000000
123.4567123456
)"
vOutput := ""
Loop, Parse, vList, `n, `r
	vOutput .= RegExReplace(A_LoopField, "(?<=\.\d\d)0000") "`r`n"
Clipboard := vOutput
MsgBox, % vOutput
and the result was:

Code: Select all

123.00
123.012345
123.10
123.123456
123.12
0.000814
0.0000814
0.00000814
0.00814
0.000814
123.456700
123.4567000000
123.4567000000000000
123.4567123456
User avatar
jeeswg
Posts: 6902
Joined: 19 Dec 2016, 01:58
Location: UK

Re: RegEx to trim floating decimal places

29 Jan 2019, 15:48

That was the output, but what was the desired output?
I think you want this: truncate trailing zeros, but maintain at least 2dp.
vOutput .= RegExReplace(A_LoopField, "\.\d\d+?\K0+$") "`r`n"
Check for a dot, a digit, and one or more digits (the +? means: grab one or more but as few as possible).
Anything before the \K is not replaced.
Check for one or more zeros after that point that are at the end of the string, remove them. Cheers.
homepage | tutorials | wish list | fun threads | donate
WARNING: copy your posts/messages before hitting Submit as you may lose them due to CAPTCHA
carno
Posts: 265
Joined: 20 Jun 2014, 16:48

Re: RegEx to trim floating decimal places

29 Jan 2019, 16:04

jeeswg wrote:
29 Jan 2019, 15:48
That was the output, but what was the desired output?
I think you want this: truncate trailing zeros, but maintain at least 2dp.
vOutput .= RegExReplace(A_LoopField, "\.\d\d+?\K0+$") "`r`n"
Check for a dot, a digit, and one or more digits (the +? means: grab one or more but as few as possible).
Anything before the \K is not replaced.
Check for one or more zeros after that point that are at the end of the string, remove them. Cheers.
Thanks for all your comments. I think this fits the bill !
SOTE
Posts: 1426
Joined: 15 Jun 2015, 06:21

Re: RegEx to trim floating decimal places

29 Jan 2019, 16:10

carno wrote:
29 Jan 2019, 16:04
jeeswg wrote:
29 Jan 2019, 15:48
That was the output, but what was the desired output?
I think you want this: truncate trailing zeros, but maintain at least 2dp.
vOutput .= RegExReplace(A_LoopField, "\.\d\d+?\K0+$") "`r`n"
Check for a dot, a digit, and one or more digits (the +? means: grab one or more but as few as possible).
Anything before the \K is not replaced.
Check for one or more zeros after that point that are at the end of the string, remove them. Cheers.
Thanks for all your comments. I think this fits the bill !
I just wanted to mention, that this will work too. Test it against the same numbers. Doesn't matter how big you make the numbers after the decimal, because it checks if they add up to zero, after 2 decimal places to the right.

Code: Select all

Loop, Parse, list, `n
{
	X := SubStr(A_Loopfield, InStr(A_Loopfield, ".") + 3, 30)  ; st is for changing place of decimal.  30 is how many numbers after decimal.
	If X = 0 
	{
	result .= SubStr(A_Loopfield, 1, 6) "`n"  ; if numbers 2 places after the decimal equal 0 then will cut them
	}
	else
	{
	result .=  A_Loopfield "`n"  ; if X not equal 0, then will put the entire number in
	}
}
To check.

Code: Select all

List =
(
123.000000
123.012345
123.100000
123.123456
123.120000
0.000814
0.0000814
0.00000814
0.000000814
0.0000000814
123.456700
123.4567000000
123.4567000000000000
123.4567123456
)
msgbox % list
Loop, Parse, list, `n
{
	X := SubStr(A_Loopfield, st := InStr(A_Loopfield, ".") + 3, 30 - st)
	If X = 0 
	{
	result .= SubStr(A_Loopfield, 1, 6) "`n"
	}
	else
	{
	result .=  A_Loopfield "`n"
	}
}
msgbox % result
Last edited by SOTE on 30 Jan 2019, 10:04, edited 4 times in total.
carno
Posts: 265
Joined: 20 Jun 2014, 16:48

Re: RegEx to trim floating decimal places

29 Jan 2019, 16:24

Thanks, SOTE. I think we have now hit the peak of perfection! :salute:
User avatar
FanaticGuru
Posts: 1906
Joined: 30 Sep 2013, 22:25

Re: RegEx to trim floating decimal places  Topic is solved

29 Jan 2019, 16:59

carno wrote:
29 Jan 2019, 12:12
Looking for a RegEx so that I can trim any number with 6 decimal places so that I can trim the leading floating zeros only after the decimal point but leave 2 zeros after the decimal point if all digits after the decimal point are zeros and 1 zero after the first non-zero digit following the decimal point if the remaining digits are also zeros? Examples:
123.000000 > 123.00
123.012345 > 123.012345
123.100000 > 123.10
123.123456 > 123.123456
123.120000 > 123.12

Answer from another thread:

Code: Select all

for k, v in [123.000000, 123.012345, 123.100000, 123.123456, 123.120000, 123.000012300]
	MsgBox % RemoveOver2TrailingZero(v)

RemoveOver2TrailingZero(x)
{
	return RegExReplace(x, "(^\d*.\d\d\d*?)(0*)$", "$1") 
}
Tested only on your example numbers and one additional one that I knew might cause problems.

FG
Hotkey Help - Help Dialog for Currently Running AHK Scripts
AHK Startup - Consolidate Multiply AHK Scripts with one Tray Icon
Hotstring Manager - Create and Manage Hotstrings
[Class] WinHook - Create Window Shell Hooks and Window Event Hooks
carno
Posts: 265
Joined: 20 Jun 2014, 16:48

Re: RegEx to trim floating decimal places

29 Jan 2019, 17:48

FanaticGuru wrote:
29 Jan 2019, 16:59
carno wrote:
29 Jan 2019, 12:12
Looking for a RegEx so that I can trim any number with 6 decimal places so that I can trim the leading floating zeros only after the decimal point but leave 2 zeros after the decimal point if all digits after the decimal point are zeros and 1 zero after the first non-zero digit following the decimal point if the remaining digits are also zeros? Examples:
123.000000 > 123.00
123.012345 > 123.012345
123.100000 > 123.10
123.123456 > 123.123456
123.120000 > 123.12

Answer from another thread:

Code: Select all

for k, v in [123.000000, 123.012345, 123.100000, 123.123456, 123.120000, 123.000012300]
	MsgBox % RemoveOver2TrailingZero(v)

RemoveOver2TrailingZero(x)
{
	return RegExReplace(x, "(^\d*.\d\d\d*?)(0*)$", "$1") 
}
Tested only on your example numbers and one additional one that I knew might cause problems.

FG
Thanks, FanaticGuru. As a main contributor to the other thread (Scripts and Functions), I appreciate your code and will be testing for anything that might cause issues.
SOTE
Posts: 1426
Joined: 15 Jun 2015, 06:21

Re: RegEx to trim floating decimal places

29 Jan 2019, 17:58

Code: Select all

Loop, Parse, list, `n
{
	X :=	SubStr(A_Loopfield, InStr(A_Loopfield, ".") + 3, 30) = 0 ? result .= SubStr(A_Loopfield, 1, 6) "`n" : result .=  A_Loopfield "`n"
}
Just in case anybody wanted or are intrigued by it, here is the "condensed version" of alternative to RegEx code.

Note - use against same list given

Moderator Note: Added code tags. ~ sinkfaze
Last edited by SOTE on 30 Jan 2019, 10:03, edited 1 time in total.
carno
Posts: 265
Joined: 20 Jun 2014, 16:48

Re: RegEx to trim floating decimal places

29 Jan 2019, 18:07

SOTE wrote:
29 Jan 2019, 17:58
Loop, Parse, list, `n
{
X := SubStr(A_Loopfield, st := InStr(A_Loopfield, ".") + 3, 30 - st) = 0 ? result .= SubStr(A_Loopfield, 1, 6) "`n" : result .= A_Loopfield "`n"
}

Just in case anybody wanted or are intrigued by it, here is the "condensed version" of alternative to RegEx code.

Note - use against same list given
Thanks, this is very helpful. I was actually thinking how to make the conversion to a shorter form. I think this now meets all the conditions!
User avatar
sinkfaze
Posts: 616
Joined: 01 Oct 2013, 08:01

Re: RegEx to trim floating decimal places

30 Jan 2019, 09:44

I don't think a single line regex for all is probably very practical for this. It can handle some but not all. My humble attempt.

Code: Select all

vList=
(
123.000000
123.012345
123.100000
123.123456
123.120000
0000.000814
)
vOut :=	""
Loop, parse, vList, `n, `r
	if	(A_Loopfield = (n :=	Round(A_LoopField,2)))
		vOut .=	n "`n"
	else	vOut .=	RegExReplace(A_LoopField,"0+\b(?!\.)") "`n"
MsgBox %	vOut
SOTE
Posts: 1426
Joined: 15 Jun 2015, 06:21

Re: RegEx to trim floating decimal places

30 Jan 2019, 10:28

I have seen some situations which submitted code can fail. Hard cases,where the decimal changes places or there is a long list of zeros followed by a positive number.

0.0000000
10.00000000000
123.000000000000000000000000001000001000000
13.0000000000000000000000000000000000000001
4356.000000000000
4356778772344455555.000000000000

Thus a protest submittal and updated version that handles this better from ATRA (Alternatives To RegEx Association) :twisted:

Code: Select all

Loop, Parse, list, `n
{
	X := SubStr(A_Loopfield, InStr(A_Loopfield, ".") + 3, 30)  ; Will search 30 digits 2 places to the right of the decimal
	If X = 0 
	{
	result .= SubStr(A_Loopfield, 1, InStr(A_Loopfield, ".") + 2) "`n"  ; if numbers 2 places after the decimal equal 0 then will cut them
	}
	else
	{
	result .=  A_Loopfield "`n"  ; if X not equal 0, then will put the entire number in
	}
}
"Compressed version"

Code: Select all

Loop, Parse, list, `n
{
X := SubStr(A_Loopfield, InStr(A_Loopfield, ".") + 3, 30) = 0 ? result .= SubStr(A_Loopfield, 1, InStr(A_Loopfield, ".") + 2) "`n" : result .=  A_Loopfield "`n"
}
Test against newer numbers and harder cases

Code: Select all

List =
(
123.0000000000000000000001
123.012345
123.100000
123.123456
123.120000
4356778772344455555.000000000000
0.0000000
0.0000814
10.00000000000
0.00000814
12.0001234
0.000000814
0.0000000814
123.456700
123.4567000000
123.456700000000000023
0.0000000
10.00000000000
123.000000000000000000000000001000001000000
13.0000000000000000000000000000000000000001
4356.000000000000
)
msgbox % list

Loop, Parse, list, `n
{
X := SubStr(A_Loopfield, InStr(A_Loopfield, ".") + 3, 30) = 0 ? result .= SubStr(A_Loopfield, 1, InStr(A_Loopfield, ".") + 2) "`n" : result .=  A_Loopfield "`n"
}

msgbox % result

Return to “Ask for Help (v1)”

Who is online

Users browsing this forum: doodles333, Google [Bot], mikeyww and 326 guests