
Diese Fragezeigt, wie man die Anzahl der Vorkommen eines bestimmten Zeichens in einer Zeichenfolge zählt. Ich möchte dies auf erweiterbare Weise und für eine Liste (nicht nur eines) bestimmter Zeichen tun.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewExpandableDocumentCommand{\countsep}{r[] m}{
% CODE HERE
}
\ExplSyntaxOff
\begin{document}
\countsep[-+]{This-is-a+test} % Count the number of - and + in the string (3)
\countsep[-+]{T+h+i+s-is-a-test} % Count the number of - and + in the string (6)
\end{document}
Antwort1
\documentclass{article}
\def\countsep#1#2{\the\numexpr0\countsepy#1\Endlist#2\Endcount}
\def\countsepy#1#2\Endlist#3\Endcount{\countsepz#1#3\Endcount
\ifx\relax#2\relax\relax\else\countsepy#2\Endlist#3\Endcount\fi}
\def\countsepz#1#2#3\Endcount{\ifx#1#2+1\fi
\ifx\relax#3\relax\else\countsepz#1#3\Endcount\fi}
\begin{document}
\countsep{-}{This-is-a+test} % Count the number of - in the string (2)
\countsep{+}{This-is-a+test} % Count the number of + in the string (1)
\countsep{-+}{This-is-a+test} % Count the number of - and + in the string (3)
\edef\z{\countsep{-+}{T+h+i+s-is-a-test}}
\z
\end{document}
Antwort2
Hier ist eine LuaLaTeX-basierte Lösung für \countsep
. Die Lösung ist eine einfache Verfeinerung einesLösungIch gab demfrühere Abfrageim Beitrag des OP erwähnt. Beachten Sie, dass \countsep
erweiterbar ist, da \directlua
und \luastring
erweiterbar sind.
Beachten Sie außerdem, dass sowohl die Suchzeichenfolge als auch die Zielzeichenfolge allgemeine UTF8-codierte Zeichen enthalten können.
% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode} % for '\luastring' macro
\newcommand\countsep[2]{\directlua{%
_ , count = unicode.utf8.gsub ( "#2" , "["..\luastring{#1}.."]" , "" )
tex.sprint ( count ) }}
\def\yy{äÖÜß}
\def\zz{ßT+h+i+s-is-a-testäÖÜß}
\edef\z{\countsep{\yy}{\zz}}
\begin{document}
\countsep{""}{This-is-a+test} % result: 0
\countsep{-+}{This-is-a+test} % result: 3
\countsep{-+}{T+h+i+s-is-a-test} % result: 6
\countsep{\yy}{\zz\zz} % result: 10
\z % result: 5
\end{document}
Antwort3
Im Folgenden wird dies in L3 mithilfe von implementiert etl
. Es verwendet das erforderliche Argument in Klammern Ihrer Frage, obwohl ich dringend davon abrate. Von der Verwendung nicht standardmäßiger Argumente wird aus einem bestimmten Grund abgeraten, []
es handelt sich normalerweise um ein optionales Argument, was hier nicht der Fall ist, und ich sehe hier keinen guten Grund für den Analyseaufwand.
Erwähnenswert:
- dies setzt voraus, dass Sie tatsächlich Vorkommen in einer Token-Liste zählen möchten (keine Stringifizierung)
- dies setzt voraus, dass Trennzeichen in Klammern gezählt werden (wenn nicht, ändern Sie die Verschachtelung
+ \vincent_count_tokens_in:nn
in\use_none:nn
). - Dies zählt korrekt, wenn eines der angegebenen Trennzeichen ein Leerzeichen ist
- Dies funktioniert nicht für Nicht-ASCII-Trennzeichen in Nicht-UTF8-Engines (pdfTeX), ansonsten funktioniert es in allen Engines
\documentclass{article}
\usepackage{xparse, etl}
\ExplSyntaxOn
\etl_new_if_in:Nnn \__vincent_if_contains_space:n { ~ } { T }
\cs_new:Npn \vincent_count_tokens_in:nn #1#2
{
\int_eval:w 0
\etl_act:nennn
\__vincent_count_tokens_in:nN
{
\__vincent_if_contains_space:nT {#1} { + \c_one_int }
\use_none:n
}
{ + \vincent_count_tokens_in:nn }
{#1}
{#2}
\scan_stop:
}
\cs_generate_variant:Nn \etl_act:nnnnn { ne }
\cs_new:Npn \__vincent_count_tokens_in:nN #1#2
{ \etl_token_if_in:nNT {#1} #2 { + \c_one_int } }
\NewExpandableDocumentCommand{\countsep}{r[] m}
{ \vincent_count_tokens_in:nn {#1} {#2} }
\ExplSyntaxOff
\begin{document}
\countsep[-+]{This-is-a+test} % Count the number of - and + in the string (3)
\countsep[- +]{T+h+i+s is{-a-}test} % Count the number of -, space and + in the string (6)
\end{document}
Abgesehen davon: Dies ist nicht besonders schnell, da etl
für jedes Listenelement nach Leerzeichen und Gruppen gesucht werden muss. Es erledigt also viel mehr im Hintergrund als die Lösung von @StevenB.Segletes. Dies ist nur erforderlich, wenn Sie wirklich Leerzeichen zählen und/oder in Gruppen rekursiv sein möchten.