我想根据某个字符(比如说)拆分字符串/
,但第一部分会进行贪婪匹配。换句话说,我的第一种方法
\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
定义了两个标记列表变量,随后可以根据需要使用。