Splitting a string greedily

Using pattern matching pdftex primitive \pdfmatch:

\documentclass{article}
%
\makeatletter
\def\cle@n@#1>#2{#2}
\newcommand{\xsplitstring}[1]{%
\ifnum\pdfmatch subcount 5 {((.+)[/])(.*)}{#1}=1 %
First: \expandafter\cle@n@\pdflastmatch2, %
Second: \expandafter\cle@n@\pdflastmatch3 % 
\else\fi
}
\makeatother
%
\begin{document}

\xsplitstring{1/2/3} 
\par
\xsplitstring{1/2/3/4} 
\par
\xsplitstring{1111111/2222/333333/444/5555555555555} 

\end{document}

results in

First: 1/2, Second: 3
First: 1/2/3, Second: 4
First: 1111111/2222/333333/444, Second: 5555555555555

You can also use LaTeX3:

\documentclass[12pt,titlepage]{article}%
\usepackage{xparse}
\ExplSyntaxOn
\tl_new:N \mafp_splitsting_tl
\NewDocumentCommand \splitstring {  m }
 {
   \tl_set:Nn \mafp_splitsting_tl { #1 }
   \tl_if_in:NnTF \mafp_splitsting_tl {/ }
       {
        \tl_reverse:N \mafp_splitsting_tl
        \exp_after:wN \mafp_splitstring:nn \mafp_splitsting_tl \q_stop
      }
      {
         Only~First:~#1
      }
 }
\cs_new:Npn \mafp_splitstring:nn #1 / #2 \q_stop
 {
  First:~ \tl_reverse:n{ #2 }~--~Second~\tl_reverse:n{ #1 }
 }
\ExplSyntaxOff

\begin{document}
\begin{tabular}{ll}
    \verb+\splitstring{1/2/3}+   & \splitstring{1/2/3}   \\
    \verb+\splitstring{1/2}+     & \splitstring{1/2}     \\
    \verb+\splitstring{1/2/3/4}+ & \splitstring{1/2/3/4} \\
    \verb+\splitstring{1}+       & \splitstring{1}       \\
\end{tabular}
\end{document}

There is also a test for only a single string.

enter image description here


For comparison, here is a LuaTeX solution (written in ConTeXt, but it should be relatively easy to translate to LaTeX)

\startluacode
  commands.splitstring = function(s)
      local sep = "/"
      -- Split the string into fragments starting at /
      local fragments = string.split(s, sep)
      -- Reconstruct the pieces as desired
      local head = table.remove(fragments, 1)
      local tail = table.concat(fragments, sep) or ""
      context("First: %s -- Second %s", head, tail)
  end
\stopluacode

\unprotected\def\splitstring#1{\ctxcommand{splitstring(\!!bs#1\!!es)}}

\starttext
\starttabulate
  \NC \type{\splitstring{1}}       \EQ \splitstring{1}       \NC \NR
  \NC \type{\splitstring{1/2}}     \EQ \splitstring{1/2}     \NC \NR
  \NC \type{\splitstring{1/2/3}}   \EQ \splitstring{1/2/3}   \NC \NR
  \NC \type{\splitstring{1/2/3/4}} \EQ \splitstring{1/2/3/4} \NC \NR
\stoptabulate
\stoptext

enter image description here

Tags:

Macros