Regexp Question: Calculation on Number with Units

What is an alternative and more semantic solution to:

\define x() 25px
\define pat() ^(\d*\.?\d*)(\D+)$
<$let y={{{ 
	[<x>splitregexp<pat>!is[blank]first[]multiply[1.46]round[]]
	[<x>splitregexp<pat>!is[blank]last[]]
	:and[join[]]
    }}} >
     <<y>>
</$let>

Remarks:
Actually user enters a font size in an inputbox (e.g. x), the line height is 1.46*x.
User is allowed to enter any number/any unit e.g. 12em, 10rem, 20pt

I’m not sure whether it’s more semantic, but here’s an alternate approach:

\function y()
[<x>search-replace:g:regexp[\D],[]multiply[1.46]round[]]
[<x>search-replace:g:regexp[\d],[]]
+[join[]]
\end

Which you could break up into component functions for greater clarity:

\function get.digits() [search-replace:g:regexp[\D],[]]
\function non.digits() [search-replace:g:regexp[\d],[]]
\function y()
[<x>get.digits[]multiply[1.46]round[]]
[<x>non.digits[]]
+[join[]]
\end

or even

\function .remove(regexp) [search-replace:g:regexp<regexp>,[]]
\function y()
[<x>.remove[\D]multiply[1.46]round[]]
[<x>.remove[\d]]
+[join[]]
\end
1 Like

Thank you @etardiff. One point

with

\function .remove(regexp) [search-replace:g:regexp<regexp>,[]]
\function y(x)
[<x>.remove[\D]multiply[1.46]round[]]
[<x>.remove[\d]]
+[join[]]
\end

I tested

<<y 12cm>>

<<y 12.77cm>>

and got

24cm

2554.cm

I assume the solution does not handle flaoting point. Am I right?

Oh, you’re right, good catch! If you do anticipate decimals, I’m not sure whether there’s any way around the more complex regex.

It’s probably no more semantic, but an interesting alternative is

\define x() 25px
\define pat() ^(\d*\.?\d*)(\D+)$
\define repl() [[$1]multiply[1.46]round[]addsuffix[$2]]
<$let 
  y={{{ [<x>search-replace::regexp<pat>,<repl>] }}} 
  z={{{ [subfilter<y>] }}} 
>
  <<z>>
</$let>

We create the string [[25]multiply[1.46]round[]addsuffix[px]], and pass it to subfilter. (Is there a good way to do that in a single filter expression?) Note that $1 and $2 in a regular expression replacement match the first and second (parenthesized) capture groups in the the regex.


One other note, if you want to avoid capturing odd input such as 0001.234, you might look to a somewhat more sophisticated regex.

Nice alternative solution! Thank you Scott.