将字符串拆分为 n x n

将字符串拆分为 n x n

我想将一个字符串拆分为 n 个字符。我知道如何逐个进行拆分:

\documentclass{article}
\makeatletter

\def\s@plit<#1#2>{%
  \ifx\empty#2%
    #1%
  \else
    #1,\s@plit<#2>%
  \fi}

\def\Split#1#2{\s@plit<#2\empty>}
\makeatother

\begin{document}
\Split{1}{123456789}
\end{document}

它给出:1,2,3,4,5,6,7,8,9

但我还想要 1,23,45,67,89 或 123,456,789......具体取决于第一个参数。

编辑

正向和反向工作,甚至与 相同foreach

在此处输入图片描述

    \documentclass{article}
    \usepackage{tikz,xparse,xstring}

\DeclareDocumentCommand{\split}{smmo}{%
    \xdef\Entree{#3}%
    \let\Sortie\empty%
    \IfBooleanTF #1
    {% sans étoile
        \loop
        \StrRight{\Entree}{#2}[\tmp]%
        \edef\Sortie{\Sortie,\tmp}%
        \StrGobbleRight{\Entree}{#2}[\Entree]%
        \unless\ifx\Entree\empty
        \repeat
        \StrGobbleLeft{\Sortie}{1}[\Sortie]%
    }
    {% avec étoile dans l'ordre inverse
        \loop
        \StrRight{\Entree}{#2}[\tmp]%
        \edef\Sortie{\tmp,\Sortie}%
        \StrGobbleRight{\Entree}{#2}[\Entree]%
        \unless\ifx\Entree\empty
        \repeat
        \StrGobbleRight{\Sortie}{1}[\Sortie]%
    }
    \IfNoValueTF{#4}{\Sortie}{\edef#4{\Sortie}}
    }

\begin{document}
\split{2}{6513782}

\split*{2}{6513782}

\split*{2}{6513782}[\bob]

\foreach \x in \bob {[\x] }

\end{document}

答案1

更新答案

我们可以反转数字串并一次添加一位数字,在请求的项目数后插入逗号(或任何您喜欢的数字);然后我们反转回去。

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand{\Split}{O{,} m m o }
 {
  \tarass_split:nnn { #1 } { #2 } { #3 }
  \IfNoValueTF { #4 } { \tl_use:N } { \tl_set_eq:NN #4 } \l_tarass_string_tl
 }

\tl_new:N \l_tarass_string_tl
\seq_new:N \l__tarass_string_seq

\cs_new_protected:Npn \tarass_split:nnn #1 #2 #3
 {% #1 = separator, #2 = number of digits, #3 = string of digits
  % clear the output token list
  \tl_clear:N \l_tarass_string_tl
  % first split into digits
  \seq_set_split:Nnn \l__tarass_string_seq { } { #3 }
  % we need to start from the end, so we reverse the sequence
  \seq_reverse:N \l__tarass_string_seq
  % add a comma after any group of #2 tokens, but not at the end
  \seq_map_indexed_inline:Nn \l__tarass_string_seq
   {
    % add the digit
    \tl_put_right:Nn \l_tarass_string_tl { ##2 }
    % maybe add a separator
    \bool_lazy_and:nnT
     {% we've done #2 digits
      \int_compare_p:n { \int_mod:nn { ##1 } { #2 } == 0 }
     }
     {% but we're not at the end
      ! \int_compare_p:n { ##1 == \seq_count:N \l__tarass_string_seq }
     }
     {% add also the separator
      \tl_put_right:Nn \l_tarass_string_tl { #1 }
     }
   }
  % reverse the string
  \tl_reverse:N \l_tarass_string_tl
 }
\ExplSyntaxOff

\newcommand{\ordinarycomma}{\mathord{,}}

\begin{document}

\Split{1}{123456789}

\Split{2}{123456789}

$\Split{3}{123456789}$ (not good)

$\Split[\ordinarycomma]{3}{123456789}$ (good)

$\Split[{{,}}]{3}{123456789}$ (good)

\Split{3}{123456789}[\temp]

\temp

\end{document}

可选参数是所需的分隔符,默认为逗号。如果您计划在数学模式下打印数字字符串,\ordinarycomma则提供。也可以用作[{{,}}]可选参数,但容易出错。

在此处输入图片描述

原始答案

这是正则表达式的工作:

\documentclass{article}

\ExplSyntaxOn
\NewDocumentCommand{\Split}{ m m o }
 {
  \tarass_split:nn { #1 } { #2 }
  \IfNoValueTF { #3 } { \tl_use:N } { \tl_set_eq:NN #3 } \l_tarass_string_tl
 }

\tl_new:N \l_tarass_string_tl

\cs_new_protected:Npn \tarass_split:nn #1 #2
 {
  \tl_set:Nn \l_tarass_string_tl { #2 }
  % we need to start from the end, so we reverse the string
  \tl_reverse:N \l_tarass_string_tl
  % add a comma after any group of #1 tokens
  \regex_replace_all:nnN { (.{#1}) } { \1\, } \l_tarass_string_tl
  % if the length of the string is a multiple of #1 a trailing comma is added
  % so we remove it
  \regex_replace_once:nnN { \,\Z } { } \l_tarass_string_tl
  % reverse back
  \tl_reverse:N \l_tarass_string_tl
 }
\ExplSyntaxOff

\begin{document}

\Split{1}{123456789}

\Split{2}{123456789}

\Split{3}{123456789}[\temp]

\temp

\end{document}

尾随的可选参数是xstring样式:如果指定了,则结果将放入该控制序列中。

在此处输入图片描述

答案2

\StrSplit包中的宏可能xstring会有帮助:

\documentclass{article}
\usepackage{xstring}
\def\split#1#2{%
    \StrSplit{#2}{#1}\tempa\tempb
    \tempa\let\tempa\empty
    \unless\ifx\tempb\empty\def\tempa{,\split{#1}\tempb}\fi
    \tempa
}
\begin{document}
\split{1}{1234567890}

编辑:此代码从最后一个字符拆分到第一个字符

\documentclass{article}
\usepackage{xstring}
\def\split#1#2{%
    \def\splitstring{#2}\let\splitresult\empty
    \loop
    \StrLen\splitstring[\tempa]%
    \StrSplit\splitstring{\number\numexpr\tempa-#1}\splitstring\tempb
    \edef\splitresult{\unless\ifx\splitstring\empty,\fi\tempb\splitresult}%
    \unless\ifx\splitstring\empty
    \repeat
    \splitresult
}
\begin{document}
\split{1}{1234567890}

\split{2}{1234567890}

\split{3}{1234567890}

\split{4}{1234567890}
\end{document}

答案3

这是一个基于 LuaLaTeX 的解决方案。它定义了一个名为的 Lua 函数strcomma,该函数使用 Lua 的内置函数string.lenstring.sub以及一个while .. do .. end循环。

LaTeX 宏\Split被设置为调用 的“包装器” strcomma。请注意,\Split可在文本和数学模式下使用——请注意,如果 TeX 处于数学模式,则逗号将被视为 math-ord 类型,而不是 math-punct 类型。

在此处输入图片描述

% !TEX TS-program = lualatex

\documentclass{article}
\directlua{function strcomma ( n , s )
  t = ""
  while string.len ( s ) > n do
    t =  "{,}" .. string.sub ( s, -n ) .. t
    s = string.sub ( s , 1, -n-1 ) 
  end
  t = s .. t
  tex.sprint ( t )
end}
\newcommand\Split[2]{\directlua{strcomma(#1,"#2")}}

\begin{document}
\Split{1}{1234}

$\Split{3}{1234567890}$
\end{document}

相关内容