字符数测试

字符数测试

我正在尝试根据变量字符串中某个字符的计数来执行特定操作。

StrCount当在 中使用 的结果时ifnumgreater,尽管值被正确处理,但仍然出现错误。

我认为它StrCount没有被处理为整数,但它确实输出了正确的值(之后2¿2似乎是一个错误)。

有什么想法可以解决这个问题吗?

平均能量损失

\documentclass[draft]{article}
\usepackage{mwe}
\usepackage{etoolbox}
\usepackage{xstring}
\newcommand{\foo}{\StrCount{test}{t}}
\newcommand{\res}{}
\ifnumgreater{\foo}{0}{
  \renewcommand{\res}{yes}
}{\renewcommand{\res}{no}}
\begin{document}
\res
\end{document}

输出

输出

错误日志

错误日志

./test.tex:7: Missing number, treated as zero.
<to be read again> 
                   \let 
l.7 \ifnumgreater{\foo}{2}
                          {
A number should have been here; I inserted `0'.
(If you can't figure out why I needed to see a number,
look up `weird error' in the index to The TeXbook.)

答案1

这是通常的问题,\StrCount{test}{t}不是数字 1,而是一组最终(但不可扩展)产生它的复杂指令。

xstring包允许使用尾随可选参数,该参数应包含定义为扩展为操作结果的控制序列。

\documentclass{article}

\usepackage{etoolbox}
\usepackage{xstring}

\newcommand{\foo}{}% just for checking it's not defined
\StrCount{test}{t}[\foo]% this stores the number of matches in \foo

\newcommand{\res}{}
\ifnumgreater{\foo}{0}
  {\renewcommand{\res}{yes}}
  {\renewcommand{\res}{no}}

\begin{document}

\res

\end{document}

使用的变化xparse,但精确的编码取决于您计划如何使用宏的信息。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\florian}{mmmO{}}
 {% #1 = regex to test for
  % #2 = token list
  % #3 = cases
  % #4 = default
  \regex_count:nxN { #1 } { #2 } \l_florian_matches_int
  \int_case:nnF { \l_florian_matches_int } { #3 } { #4 }
 }
\int_new:N \l_florian_matches_int
\cs_generate_variant:Nn \regex_count:nnN { nx }
\ExplSyntaxOff

\newcommand{\testA}{test}
\newcommand{\testB}{tes}
\newcommand{\testC}{es}
\newcommand{\testD}{ttest}

\newcommand{\res}{} % initialize

\begin{document}

\florian{t}{\testA}{
 {0}{\renewcommand{\res}{no}}
 {1}{\renewcommand{\res}{yes, one}}
}[\renewcommand{\res}{yes, many}]

1. \res

\florian{t}{\testB}{
 {0}{\renewcommand{\res}{no}}
 {1}{\renewcommand{\res}{yes, one}}
}[\renewcommand{\res}{yes, many}]

2. \res

\florian{t}{\testC}{
 {0}{\renewcommand{\res}{no}}
 {1}{\renewcommand{\res}{yes, one}}
}[\renewcommand{\res}{yes, many}]

3. \res

\florian{t}{\testD}{
 {0}{\renewcommand{\res}{no}}
 {1}{\renewcommand{\res}{yes, one}}
 {3}{\renewcommand{\res}{Three!}}
}[\renewcommand{\res}{yes, many}]

4. \res

\end{document}

在此处输入图片描述

答案2

为软件包量身定制listofitems,提供完全可扩展的结果。在下面的 MWE 中,搜索“序列”可以是单个字符(如图所示),也可以是多标记序列(例如“is”),它同样会\thecharcount提供2

通常,listofitems用于解析输入列表中 [可能嵌套] 分隔符之间的字段。此处,如果我们使用所需的搜索字符串作为字段分隔符,则找到的搜索字符串(又称字段分隔符)的实例数将是所定位字段的数量(称为列表长度)减 1。

\documentclass{article}
\usepackage{listofitems}
\newcommand\countchars[2]{%
  \setsepchar{#1}%
  \readlist\mylist{#2}%
  \edef\thecharcount{\the\numexpr\listlen\mylist[]-1\relax}%
  \thecharcount
}
\begin{document}
\def\mydata{This is a test of the emergency broadcast system}
\countchars{e}{\mydata}

There are \thecharcount{} instances of the sequence ``e'' in ``\mydata''

\countchars{c}{\mydata}

There are \thecharcount{} instances of the sequence ``c'' in ``\mydata''
\end{document}

在此处输入图片描述


举一个如何使用和利用嵌套搜索的例子:

\documentclass{article}
\usepackage{listofitems}
\begin{document}
\def\mydata{This is a test of the emergency broadcast system}
\setsepchar{e/s}
\readlist\mylist{\mydata}

There are \the\numexpr\listlen\mylist[]-1\relax{} instances of the sequence 
  ``\mylistsep[1]'' in ``\mydata''

\foreachitem\i\in\mylist{%
  \def\tlev{\mylistsep[\icnt]}%
  \def\blev{\mylistsep[\icnt,1]}%
  There are \the\numexpr\listlen\mylist[\icnt]-1\relax{} instances of ``\blev'' between 
  \ifnum\icnt=1\relax the beginning \else \tlev$_{\the\numexpr\icnt-1\relax}$ \fi and 
  \ifnum\icnt=\listlen\mylist[]\relax the end\else e$_{\icnt}$\fi.\par
}
\end{document}

在此处输入图片描述

相关内容