使用 siunitx 处理已处理的数字

使用 siunitx 处理已处理的数字

我正在尝试操作经过预处理的数字,例如,将 1,000,000.50 变为 1.000.000,去掉精度并用“,”替换千位分隔符。

\documentclass[12pt]{article}
\usepackage{siunitx}

\ExplSyntaxOn
\NewDocumentCommand{\removeComma}{m}
 {
  \tl_set:Nn \l_tmpa_tl { #1 }
  \regex_replace_all:nnN { (\,) } { } \l_tmpa_tl
  \tl_use:N \l_tmpa_tl
 }
\ExplSyntaxOff

\begin{document}

\num[round-precision=0, group-separator = {.}]]{\removeComma{1,000,000.00}}

\end{document}

然而,我最终得到了一个错误

Package siunitx error: Invalid number '\removeComma{1,000,000.00}'

答案1

为什么不使用已经提供的input-ignore服务siunitx

\documentclass[12pt]{article}
\usepackage{siunitx}
\sisetup{
  input-decimal-markers={.},
  input-ignore={,},
}

\begin{document}

% I've replaced "group-separator={.}" with "group-digits=none" because, well,
% having the group-separator equal to 'output-decimal-marker' is rather
% confusing.
\num[round-precision=0,group-digits=none]{1,000,000.00}

\end{document}

在此处输入图片描述

编辑考虑到注释中要求使用点作为组分隔符、逗号作为小数点标记以及“去掉小数点”,您可以使用:

\documentclass[12pt]{article}
\usepackage{siunitx}
\sisetup{
  input-decimal-markers={.},
  input-ignore={,},
  output-decimal-marker={,},
  group-separator={.},
  % by "getting rid of the decimal", I presume you mean rounding.
  round-mode=places,
  round-precision=0,
  round-half=even
}

\begin{document}

\num{1,000,000.50}

\end{document}

结果:

在此处输入图片描述

我猜,如果您真的想“去掉小数”而不是正确舍入,您可以使用该evaluate-expression选项。无论哪种方式,我的一般建议是使用提供的灵活结构,siunitx而不是尝试自己解析数字。

答案2

不可扩展的事实\regex_replace_all:nnN不应阻止您在 的参数\num(或任何其他仅扩展的上下文)中使用它的结果。您只需将结果存储在宏中并将该宏放入 的参数中\num。事实上,执行一个扩展步骤宏是一种操作,根据定义,它总是在仅扩展的上下文中起作用!

\documentclass{article}
\usepackage{siunitx}

\ExplSyntaxOn
% #1 must be a control sequence token
\NewDocumentCommand \removeComma { m m }
  {
    \tl_set:Nn #1 {#2}
    \regex_replace_all:nnN { \, } { } #1
  }
\ExplSyntaxOff

\begin{document}

\removeComma{\myresult}{1,000,000.50}%
\num[round-mode=places, round-precision=0, round-half=even, group-separator=.]%
  {\myresult}

\end{document}

在此处输入图片描述

答案3

实验表明,有多个步骤,并且使用正则表达式,这些步骤必须按照正确的顺序完成(有时使用第二个 tmp 变量)。

将任务分解为单独的部分,并保持它们分离。

实验是为了尝试各种方法。正则表达式输出版本显示在 (A) 下:

正则表达式

正则表达式是最紧凑的:\tl_remove\tl_replace等效\str物在这里仅部分有用,尽管可以使用(具有更多的代码行和一些步骤逻辑)。

并且看起来si也正在输入其自己的格式。

平均能量损失

\documentclass[12pt]{article}
\usepackage{siunitx}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand { \removeCommaA } { o m }
 {
    TL ~ Regex ~ \IfValueT { #1 } { #1 }  \tex_par:D
    #2 $\mapsto$ 
  \tl_set:Nn \l_tmpa_tl { #2 }
  \regex_replace_all:nnN { \.\d{2} } { } \l_tmpa_tl
    \IfValueF { #1 } { \tl_set_eq:NN \l_tmpb_tl \l_tmpa_tl }
  \regex_replace_all:nnN { \, } {  } \l_tmpa_tl
    \IfValueT { #1 } { \use:c { #1 } }
  { \tl_use:N \l_tmpa_tl }
    \IfValueF { #1 } { 
                \regex_replace_all:nnN { \, } { \. } \l_tmpb_tl
                \tex_par:D >> ~ \tl_use:N \l_tmpb_tl 
                }
 
 }
%\NewExpandableDocumentCommand{\removeCommaB}{m}
% {
%  \tl_set:Nn \l_tmpa_tl { #1 }
%  \regex_replace_all:nnN { (\,) } { } \l_tmpa_tl
%  \tl_use:N \l_tmpa_tl 
% }
\NewDocumentCommand { \removeCommaC } { o m }
 {
    TL ~ Remove ~ \IfValueT { #1 } { #1 }  \tex_par:D
  \tl_set:Nn \l_tmpa_tl { #2 }
    \tl_remove_all:Nn \l_tmpa_tl { , }
    \IfValueT { #1 } { \use:c { #1 } }
  { \tl_use:N \l_tmpa_tl }
 }
 
\NewDocumentCommand { \removeCommaD } { o m }
 {
        Str ~ Remove ~ \IfValueT { #1 } { #1 } \tex_par:D
  \str_set:Nn \l_tmpa_str { #2 }
    \str_remove_all:Nn \l_tmpa_str { , }
    \IfValueT { #1 } { \use:c { #1 } }
   { \str_use:N \l_tmpa_str }
 }
 
\ExplSyntaxOff

\begin{document}

(A) \removeCommaA{1,000,000.00}

\removeCommaA[num]{1,000,000.00}

\removeCommaA[numprint]{1,000,000.00}
 
%(B) \num[round-precision=0, group-separator = {.}]{\removeCommaB{1,000,000.00}}

(C) \removeCommaC{1,000,000.00}

\removeCommaC[num]{1,000,000.00}

(D) \removeCommaD{1,000,000.00}

\removeCommaD[num]{1,000,000.00}


\end{document}

相关内容