Take the 2-minute tour ×
TeX - LaTeX Stack Exchange is a question and answer site for users of TeX, LaTeX, ConTeXt, and related typesetting systems. It's 100% free, no registration required.

I want to split a character string n by n. I know how to do that 1 by 1 :

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

It gives : 1,2,3,4,5,6,7,8,9

But I also want 1,23,45,67,89 or 123,456,789 ... depending from the first parameter.

EDIT

Work straight and reverse, even with foreach.

enter image description here

    \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}
share|improve this question

2 Answers 2

up vote 5 down vote accepted

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

share|improve this answer
    
I agree it is a job for a regular expression, but I did know that such a package exists. Thanks! –  Tarass Apr 11 at 21:19
    
I didn't know ... ! of course. –  Tarass Apr 12 at 5:52

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}
share|improve this answer
    
I thought about that macro, but I don't know how to have 1,234,567,890 instead of 123,456,789,0 ? –  Tarass Apr 11 at 21:08
    
Dégouté sur ce coup. Comme souvent ici... –  unbonpetit Apr 11 at 21:32
    
On risque une punition à parler français ;-) Pourquoi dégoûté ? Elle était bien ta solution, il ne restait plus qu'à retourner le sens de lecture. Ce qui génial ici c'est qu'il y a des gens très pointus dans plein de domaines et tu apprends à chaque fois quelque chose: ce coup-ci c'est le package pour les expressions régulières, c'est super utile. –  Tarass Apr 11 at 21:43
    
Je me fiche des punitions sur ce site comme de ma première sucette. Dégouté parce que lorsque tu chercheras une solution pour quelqu'un et que tu verras qu'il en a (trop vite) accepté une autre et que la tienne en devient inutile et que tu as cherché pour que dalle, tu sauras pourquoi on peut être dégouté. Voilà. Aller, la punition, maintenant. –  unbonpetit Apr 11 at 21:50
    
J'ai ajouté un point à ta réponse, elle n'était pas complète, donc pas acceptable. Il y a des gens ici qui donnent les réponses en 5 minutes parce qu'ils maîtrisent vraiment les outils. Egreg à presque 100 fois plus de points que toi et toi 3 fois plus que moi. Si cela ne t'amuse pas de résoudre le casse-tête, pourquoi y passer tant de temps, qu'elle récompense peut-on espérer à par le plaisir de trouver, d'apprendre et de rendre service. Encore une fois merci. –  Tarass Apr 11 at 21:58

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.