![检查列表中的至少一个子字符串是否可以在字符串中找到](https://linux22.com/image/441030/%E6%A3%80%E6%9F%A5%E5%88%97%E8%A1%A8%E4%B8%AD%E7%9A%84%E8%87%B3%E5%B0%91%E4%B8%80%E4%B8%AA%E5%AD%90%E5%AD%97%E7%AC%A6%E4%B8%B2%E6%98%AF%E5%90%A6%E5%8F%AF%E4%BB%A5%E5%9C%A8%E5%AD%97%E7%AC%A6%E4%B8%B2%E4%B8%AD%E6%89%BE%E5%88%B0.png)
有几种解决方案既集成在 TeX 中,也在此提出,用于检查是否可以在给定字符串中找到子字符串(例如IfSubStr
,IfStringInList
等等)。例如,\instringTF
(定义如下:https://tex.stackexchange.com/a/26873/61517) 用作
\instringTF{graph}{graphs}{We have data}{We do not have data}
给出
We have data
现在,我想将其扩展到几个可能的子字符串,即如下调用
\instringTF{graph,images}{graphs}{We have data}{We do not have data}
这仍然应该评估为
We have data
尽管
\instringTF{graph,images}{image}{We have data}{We do not have data}
应评估为
We do not have data
该问题也有解决方案吗?
编辑:Peter Grill 建议使用来自https://tex.stackexchange.com/a/350818/61517。我实现了它,结果是:
\documentclass[%
reprint,
amsfonts,
floatfix,
amsmath,amssymb,
aps,
pra,
]{revtex4-2}
\usepackage{graphicx}% Include figure files
%\usepackage{dcolumn}% Align table columns on decimal point
%\usepackage{bm}% bold math
\usepackage{todonotes}
%\usepackage{siunitx}
%\usepackage{caption}
\usepackage{letltxmacro}
\usepackage{xstring}
\usepackage[labelformat=simple]{subcaption}
\usepackage{float}
\usepackage{xparse}
\usepackage{substr}
\makeatletter
\renewcommand{\todo}[2][]{\tikzexternaldisable\@todo[#1]{#2}\tikzexternalenable}
\makeatother
\usepackage{hyperref}
\ExplSyntaxOn
\cs_new_protected:Nn \grill_str_multicase:nnTF
{
\seq_set_split:Nnn \l__grill_str_multicase_cases_seq { } { #2 }
\tl_clear:N \l__grill_str_multicase_cases_tl
\int_step_inline:nnnn { 1 } { 2 } { \seq_count:N \l__grill_str_multicase_cases_seq }
{
\seq_set_split:Nnx \l__grill_str_multicase_subcases_seq { }
{ \seq_item:Nn \l__grill_str_multicase_cases_seq { ##1 } }
\seq_map_inline:Nn \l__grill_str_multicase_subcases_seq
{
\tl_put_right:Nx \l__grill_str_multicase_cases_tl
{
{\exp_not:n{####1}}{\seq_item:Nn \l__grill_str_multicase_cases_seq { ##1 + 1}}
}
}
}
\str_case:nVTF { #1 } \l__grill_str_multicase_cases_tl { #3 } { #4 }
}
\cs_generate_variant:Nn \seq_set_split:Nnn { Nnx }
\cs_new_protected:Nn \grill_str_multicase:nn
{
\grill_str_multicase:nnTF { #1 } { #2 } { } { }
}
\cs_new_protected:Nn \grill_str_multicase:nnT
{
\grill_str_multicase:nnTF { #1 } { #2 } { #3 } { }
}
\cs_new_protected:Nn \grill_str_multicase:nnF
{
\grill_str_multicase:nnTF { #1 } { #2 } { } { #3 }
}
\NewDocumentCommand{\IfStringCaseX}{mmo}
{
\IfNoValueTF{#3}
{ \grill_str_multicase:nn { #1 } { #2 } }
{ \grill_str_multicase:nnF { #1 } { #2 } { #3 } }
}
\ExplSyntaxOff
\newcommand{\ConditionalText}[1]{%
\IfStringCaseX{#1}
{
{{images}{graphs}}
{%
We have images/graphs
}
}[{Error: Unknown parameter ``#1'' to ConditionalText}]%
}
\makeatother
\begin{document}
\ConditionalText{images/subx.tikz}
\ConditionalText{images}
\end{document}
这里,第一行包含
\ConditionalText{images/subx.tikz}
产生Unknown parameter
,而第二行
\ConditionalText{images}
生产
We have images/graphs
即,所提出的解决方案不适用于我的用例。
答案1
映射可能的子字符串列表;如果找到匹配项,则通过将条件设置为 true 来中断映射。
然后检查条件是真还是假。
\documentclass{article}
\ExplSyntaxOn
\NewDocumentCommand{\instringTF}{mmmm}
{% #1 = list of possible substrings, #2 = string, #3 = true text, #4 = false text
\arclupus_instring:nnnn { #1 } { #2 } { #3 } { #4 }
}
\bool_new:N \l_arclupus_instring_bool
\cs_new_protected:Nn \arclupus_instring:nnnn
{
\bool_set_false:N \l_arclupus_instring_bool
\clist_map_inline:nn { #1 }
{
\str_if_in:nnT { #2 } { ##1 }
{% ##1 is a substring, no need to check further
\clist_map_break:n { \bool_set_true:N \l_arclupus_instring_bool }
}
}
\bool_if:NTF \l_arclupus_instring_bool { #3 } { #4 }
}
\ExplSyntaxOff
\begin{document}
\instringTF{graph}{graphs}{We have data}{We do not have data}
\instringTF{graph,images}{graphs}{We have data}{We do not have data}
\instringTF{graph,images}{image}{We have data}{We do not have data}
\end{document}