Split a character string n by n

The \StrSplit macro from the xstring package may help:

\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}

EDIT : This code split from last char to first

\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}

This is a job for regular expressions:

\documentclass{article}
\usepackage{xparse,l3regex}

\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}

The trailing optional argument is xstring style: if it's specified, then the result is put into that control sequence.

enter image description here


Here's a LuaLaTeX-based solution. It defines a Lua function called strcomma, which uses Lua's built-in functions string.len and string.sub along with a while .. do .. end loop.

The LaTeX macro \Split is set up as a "wrapper" that invokes strcomma. Note that \Split may be used in both text and math mode -- care is taken so that, if TeX is in math mode, the commas are treated as being of type math-ord, not math-punct.

enter image description here

% !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}

Tags:

Strings