我想根据参数是否包含特殊字符来实现 if-then-else。我应该在这里查看:http://www.tug.org/TUGboat/Articles/tb28-1/tb88glister.pdf,或者有人知道更简单的方法吗?
答案1
\documentclass{article}
\usepackage{xstring}
\begin{document}
\IfSubStr{Rotterdam}{otter}{ true }{ false }
\end{document}
答案2
\makeatletter
\def\instring#1#2{TT\fi\begingroup
\edef\x{\endgroup\noexpand\in@{#1}{#2}}\x\ifin@}
\makeatother
\def\mystring{abcdef}
\if\instring{a}{abcdef}\message{YES}\else\message{NO}\fi
\if\instring{a}{\mystring}\message{YES}\else\message{NO}\fi
在这两种情况下,LaTeX 都应该显示“YES”。不过,这取决于您感兴趣的“特殊字符”类型。
更强大的宏expl3
:
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\instringTF}{mmmm}
{
\oleks_instring:nnnn { #1 } { #2 } { #3 } { #4 }
}
\tl_new:N \l__oleks_instring_test_tl
\cs_new_protected:Nn \oleks_instring:nnnn
{
\tl_set:Nn \l__oleks_instring_test_tl { #1 }
\regex_match:nnTF { \u{l__oleks_instring_test_tl} } { #2 } { #3 } { #4 }
}
\ExplSyntaxOff
\begin{document}
\instringTF{=}{a=b}{true}{false} (should be true)
\instringTF{=}{ab}{true}{false} (should be false)
\instringTF{à}{città}{true}{false} (should be true)
\instringTF{à}{mela}{true}{false} (should be false)
\end{document}
更强大的版本;该\instringxTF
宏有一个可选参数,用于选择匹配项(默认 1,第一个匹配项)。第一个强制参数是要查找的文本,第二个是输入。
第三个强制参数可以包含#1
代表所选匹配之前的文本和#2
匹配之后的文本。同样,第四个强制参数可以包含#1
输入文本。
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\instringxTF}{O{1}mmmm}
{% #1 = number of match
% #2 = test tokens
% #3 = input to check for match
% #4 = code to execute for matches
% #1 stands for the pre-match
% #2 for the post-match
% #5 = code to execute for no match
% #1 for the input text
\oleks_instring:nnnnn { #1 } { #2 } { #3 } { #4 } { #5 }
}
\cs_generate_variant:Nn \seq_use:Nn { NV }
\tl_new:N \l__oleks_instring_test_tl
\seq_new:N \l__oleks_instring_parts_tl
\seq_new:N \l__oleks_instring_pre_seq
\seq_new:N \l__oleks_instring_post_seq
\cs_new_protected:Nn \__oleks_instring_match:nn {}
\cs_generate_variant:Nn \__oleks_instring_match:nn { ff }
\cs_new_protected:Nn \__oleks_instring_nomatch:n {}
\cs_new_protected:Nn \oleks_instring:nnnnn
{
\tl_set:Nn \l__oleks_instring_test_tl { #2 }
\regex_match:nnTF { \u{l__oleks_instring_test_tl} } { #3 }
{ \__oleks_instring_match_do:nnn { #1 } { #3 } { #4 } }
{
\cs_set_protected:Nn \__oleks_instring_nomatch:n { #5 }
\__oleks_instring_nomatch:n { #3 }
}
}
\cs_new_protected:Nn \__oleks_instring_match_do:nnn
{
\cs_set_protected:Nn \__oleks_instring_match:nn { #3 }
\regex_split:nnN
{ \u{l__oleks_instring_test_tl} }
{ #2 }
\l__oleks_instring_parts_seq
\seq_clear:N \l__oleks_instring_pre_seq
\seq_clear:N \l__oleks_instring_post_seq
\int_step_inline:nnnn { 1 } { 1 } { #1 }
{
\seq_put_right:Nx \l__oleks_instring_pre_seq
{ \seq_item:Nn \l__oleks_instring_parts_seq { ##1 } }
}
\int_step_inline:nnnn { #1 + 1 } { 1 } { \seq_count:N \l__oleks_instring_parts_seq }
{
\seq_put_right:Nx \l__oleks_instring_post_seq
{ \seq_item:Nn \l__oleks_instring_parts_seq { ##1 } }
}
\__oleks_instring_match:ff
{ \seq_use:NV \l__oleks_instring_pre_seq \l__oleks_instring_test_tl }
{ \seq_use:NV \l__oleks_instring_post_seq \l__oleks_instring_test_tl }
}
\ExplSyntaxOff
\begin{document}
\instringxTF{=}{a=b=c}{pre: #1, post: #2}{no match: #1}
\instringxTF[2]{=}{a=b=c}{pre: #1, post: #2}{no match: #1}
\instringxTF{=}{abc}{pre: #1, post: #2}{no match: #1}
\instringxTF{é}{abécdéf}{pre: #1, post: #2}{no match: #1}
\end{document}
答案3
\pdfmatch{<pattern>}{<string>}
由 pdfTeX 提供。此命令实现模式匹配(使用 POSIX 正则表达式的语法),<pattern>
在 中搜索<string>
。如果模式无效,则命令扩展为 -1,如果未找到匹配项,则扩展为 0,如果找到匹配项,则扩展为 1。此原语是在 pdfTeX 1.30.0 中引入的。
是
是
否
\documentclass{article}
\newcommand{\instring}[4]{%
% \instring{<pattern>}{<string>}{<true>}{<false>}
% pattern = sought after string
% string = string to search
\ifnum\pdfmatch{#1}{#2}=1
#3%
\else
#4%
\fi
}
\begin{document}
\def\mystring{abcdef}
\instring{a}{abcdef}{Yes}{No}% Yes
\instring{abc}{\mystring}{Yes}{No}% Yes
\instring{acb}{\mystring}{Yes}{No}% No
\end{document}
答案4
在 OpTeX 中,我们有\isinlist
宏来实现这些目的。语法是
\isinlist <list>{<substring>}\iftrue true branch\else false branch\fi
可以<list>
是隐式的(如\macro
)或显式的(如{text}
)。例如:
\def\mystring{abcdef}
\isinlist {abcdef}{a}\iftrue \message{YES}\else\message{NO}\fi
\isinlist \mystring{a}\iftrue \message{YES}\else\message{NO}\fi
\bye
两种情况的结果都是肯定的。