贪婪地分割字符串

贪婪地分割字符串

我想根据某个字符(比如说)拆分字符串/,但第一部分会进行贪婪匹配。换句话说,我的第一种方法

\makeatletter
\newcommand{\splitstring}[1]{\@mysplit#1\@nil}
\def\@mysplit#1/#2\@nil{First: #1 -- Second: #2}
\makeatother

导致,\splitstring{1/2/3}First: 1 – Second: 2/3我希望它导致First: 1/2 – Second: 3。有没有简单的 TeX 解决方案?

答案1

xstring包可能会有帮助

\input xstring.tex
\def\splitstring#1#2{%
    \StrCount{#1}{#2}[\nbmatch]%
    \StrCut[\nbmatch]{#1}{#2}\strfirst\strsecond
    First : \strfirst\par
    Second : \strsecond
}

\splitstring{1/2/3}{/}
\bye

答案2

使用模式匹配pdftex原语\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}

结果是

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

答案3

您还可以使用 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}

还有一个仅针对单个字符串的测试。

在此处输入图片描述

答案4

l3regex包具有贪婪和惰性正则表达式搜索。

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

\ExplSyntaxOn
\NewDocumentCommand{\splitstring}{sm}
 {
  \IfBooleanTF #1
   {
    \mafp_showstring:n { #2 }
   }
   {
    \mafp_splitstring:n { #2 }
   }
 }

\tl_new:N \l_mafp_firstpart_tl
\tl_new:N \l_mafp_secondpart_tl
\tl_new:N \l_mafp_string_tl

\cs_new_protected:Npn \mafp_showstring:n #1
 {
  % check if a / is in the string to begin with
  \regex_match:nnTF { / } { #1 }
   { % true case
    \tl_set:Nn \l_mafp_string_tl { #1 }
    \regex_replace_once:nnN 
     { (.*)/(.*) } % search string
     { First: \cS\  \1 \cS\  -- \cS\  Second: \cS\  \2 } % replacement string
     \l_mafp_string_tl
    \tl_use:N \l_mafp_string_tl
   }
   { % false case
    No ~ slash: ~ #1
   }
 }
\cs_new_protected:Npn \mafp_splitstring:n #1
 {
  \regex_match:nnTF { / } { #1 }
   {
    \tl_set:Nn \l_mafp_firstpart_tl  { #1 }
    \tl_set:Nn \l_mafp_secondpart_tl { #1 }
    \regex_replace_once:nnN { (.*)/.* } { \1 } \l_mafp_firstpart_tl
    \regex_replace_once:nnN { .*/(.*) } { \1 } \l_mafp_secondpart_tl
    % The following lines are just for showing the result
    First:~\tl_use:N \l_mafp_firstpart_tl \ --~ Second:~\tl_use:N \l_mafp_secondpart_tl
   }
   {
    \tl_set:Nn \l_mafp_firstpart_tl  { #1 }
    \tl_set:Nn \l_mafp_secondpart_tl { }
    % The following lines are just for showing the result
    No ~ slash:~#1
   }
 }

\ExplSyntaxOff

\begin{document}
\splitstring{1/2/3}

\splitstring{1}
\end{document}

我还定义了\splitstring*简单地打印两个部分;主函数\mafp_splitstring:n定义了两个标记列表变量,随后可以根据需要使用。

相关内容