统计指定字符串中字符数的命令

统计指定字符串中字符数的命令

有没有办法计算指定字符串中的字符数?

假设我有以下代码。

\documentclass{article}
\newcommand{\numchars}[1]{\noindent The string ``#1" has ? characters.\\}
\begin{document}
\numchars{everything}
\numchars{that's not it!}
\numchars{weird}
\end{document}

我怎样才能让它像这样显示正确的字符数

字符数

无需手动计数?

答案1

如果您的参数包含宏,则答案需要更改。空格算作字符,但您可以根据需要进行调整。

\documentclass{article}
\usepackage{stringstrings}
\newcommand{\numchars}[1]{\noindent The string ``#1'' has \stringlength{#1} characters.\\}
\begin{document}
\numchars{everything}
\numchars{that's not it!}
\numchars{weird}
\end{document}

在此处输入图片描述

这是不计算空格的版本。

\documentclass{article}
\usepackage{stringstrings}
\newcommand{\numchars}[1]{%
  \convertchar[q]{#1}{ }{}%
  \noindent The string ``#1'' has \stringlength{\thestring} characters.\\
}
\begin{document}
\numchars{everything}
\numchars{that's not it!}
\numchars{weird}
\end{document}

在此处输入图片描述

如果你只想计算字母字符(忽略数字、空格和标点符号)

\documentclass{article}
\usepackage{stringstrings}
\newcommand{\numchars}[1]{%
  \convertchar[q]{#1}{ }{}%
  \alphabetic[q]{\thestring}%
  \noindent The string ``#1'' has \stringlength{\thestring} characters.\\
}
\begin{document}
\numchars{everything}
\numchars{that's not it!}
\numchars{weird}
\end{document}

在此处输入图片描述

答案2

即使 OP 表示他/她对基于 LuaLaTeX 的解决方案不感兴趣,但其他人可能仍然重视这样的解决方案。:-)

以下解决方案适用于 UTF8 编码的字符串。由于 ASCII 编码的字符会自动进行 UTF8 编码,因此该解决方案也适用于 ASCII 编码的字符串。

在此处输入图片描述

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{fontspec}
\usepackage{luacode} % for "\luastring" macro
\newcommand{\numchars}[1]{\noindent The string ``#1'' has 
    \directlua{tex.sprint(unicode.utf8.len(\luastring{#1}))} 
    characters.\par}

\begin{document}
\numchars{everything}
\numchars{öüß}
\end{document}

在旁边:如果 Lua 端代码不恰当地使用了 函数string.len而不是unicode.utf8.len,则宏\numchars将报告öüß有 6 个字符。发生这种情况是因为 中的 3 个字符中的每一个öüß在 utf8 系统中都使用 2 个字节进行编码。(该函数str.len执行字节计数而不是直接字符计数;如果每个字符都使用 1 个字节进行编码,则这是可以的,这是 ASCII 编码系统的情况,但不是大多数其他编码系统的情况。)同样,字符串ø§¶®€œ¥√DZ将被错误地诊断为有 22 个 [!] 而不是 10 个字符,因为 和 都使用3 个字节进行编码,其余 8 个字符每个使用 2 个字节进行编码。显然,在当前上下文中使用该函数很重要unicode.utf8.len

答案3

命令\newcommand{\numchars}[1]... 运行良好,但我在包\stringlength中遇到了一些问题stringstrings。它似乎对字符数有 500 个限制,如果超过该限制,则返回零。例如,代码:

\documentclass[11pt]{amsart}
\usepackage{stringstrings}
\newcommand{\numchars}[1]{\noindent The string ``#1'' has \stringlength{#1} characters.\\}

\begin{document}
\numchars{Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna. Donec vehicula augue eu neque. Pellentesque habitant morbi tris- tique senectus et netus et malesuada fames ac turpis egestas. Mauris ut leo. Cras viverra metus rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices. Phasellus eu tellus sit amet tortor gravida placerat. Integer sapien est, iaculis in, pretium quis, viverra ac, nunc. Praesent eget sem vel leo ultrices bibendum. Aenean faucibus. Morbi dolor nulla, malesuada eu, pul- vinar at, mollis ac, nulla. Curabitur auctor semper nulla. Donec varius orci eget risus. Duis nibh mi, congue eu, accumsan eleifend, sagittis quis, diam. Duis eget orci sit amet orci dignissim rutrum.}
\end{document}

返回:

\StrLen包中的命令xstring似乎效果更好。文档:

\documentclass[11pt]{amsart}
\usepackage{xstring}
\newcommand{\numchars}[1]{\noindent The string ``#1'' has {\StrLen{#1}} characters.\\}

\begin{document}
\numchars{Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Ut purus elit, vestibulum ut, placerat ac, adipiscing vitae, felis. Curabitur dictum gravida mauris. Nam arcu libero, nonummy eget, consectetuer id, vulputate a, magna. Donec vehicula augue eu neque. Pellentesque habitant morbi tris- tique senectus et netus et malesuada fames ac turpis egestas. Mauris ut leo. Cras viverra metus rhoncus sem. Nulla et lectus vestibulum urna fringilla ultrices. Phasellus eu tellus sit amet tortor gravida placerat. Integer sapien est, iaculis in, pretium quis, viverra ac, nunc. Praesent eget sem vel leo ultrices bibendum. Aenean faucibus. Morbi dolor nulla, malesuada eu, pul- vinar at, mollis ac, nulla. Curabitur auctor semper nulla. Donec varius orci eget risus. Duis nibh mi, congue eu, accumsan eleifend, sagittis quis, diam. Duis eget orci sit amet orci dignissim rutrum.}
\end{document}

返回:

答案4

Mico 指出的问题在 @cfr 的解决方案中只需使用 LuaTeX 或 XeTeX 即可解决。如果受限于 pdfTeX 引擎,一个可能的解决方案是使用功能非常强大的软件包l3regex

编辑:正如 egreg 指出的那样,我不知道有这么多的多字节前缀。

\documentclass{scrartcl}
\usepackage{xparse,l3regex}
\usepackage[T1]{fontenc}
\usepackage[utf8]{inputenc}

\ExplSyntaxOn
\NewDocumentCommand \numchars { s m }
 {
  \group_begin:
  \tl_set:Nn \l_tmpa_tl { #2 }
  \IfBooleanF { #1 } { \tl_replace_all:Nnn \l_tmpa_tl { ~ } { x } }
  \regex_replace_all:nnN { [\x{C2}-\x{DF}].   } { x } \l_tmpa_tl
  \regex_replace_all:nnN { [\x{E0}-\x{EF}]..  } { x } \l_tmpa_tl
  \regex_replace_all:nnN { [\x{F0}-\x{F4}]... } { x } \l_tmpa_tl

  The ~ string ~ ``#2'' ~ has ~ \tl_count:N \l_tmpa_tl \space characters
  \IfBooleanT { #1 } { ~ (ignoring ~ whitespace)} .\par
  \group_end:
 }
\ExplSyntaxOff

\begin{document}
  \numchars{ßöü—} % em-dash
  \numchars{everything}
  \numchars*{everything}
  \numchars{that's not it!}
  \numchars*{that's not it!}
  \numchars{weird}
  \numchars*{weird}
\end{document}

结果

字符串“ßöü—” 有 4 个字符。
字符串“everything” 有 10 个字符。
字符串“everything” 有 10 个字符(忽略空格)。
字符串“that's not it!” 有 14 个字符。
字符串“that's not it!” 有 12 个字符(忽略空格)。
字符串“weird” 有 5 个字符。
字符串“weird” 有 5 个字符(忽略空格)。

相关内容