LaTeX count number of occurrences of a character in a string
Using expl3
you can split the token list into items and then count the items (less 1):
2
4
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
% \CountSubStr{<substring>}{<string>}
\NewDocumentCommand{\CountSubStr}{ m m }{
\seq_set_split:Nnn \l_tmpa_seq { #1 } { #2 }
\int_eval:n {(\seq_count:N \l_tmpa_seq) - 1 }
}
\ExplSyntaxOff
\begin{document}
\CountSubStr{~}{This~is a ~test}% 2
\CountSubStr{yes}{a yes b yes c yes deyesfg yehs ij}% 4
\end{document}
For good measure, a LuaLaTeX-based solution:
\documentclass{article}
\usepackage{luacode} % for '\luastring' and '\luaexec' macros
\newcommand\tildecount[1]{\luaexec{
_ , count = string.gsub ( \luastring{#1} , "~" , "~" )
tex.sprint ( count ) }}
\begin{document}
\tildecount{This~is a ~test}
\tildecount{~~~~----&&&&****____####~~~~$$$$~~~~}
\end{document}
Addendum: The \tildecount
macro can easily be generalized to take a second input, viz., the string whose occurrences should be counted. The code for the generalized macro would be as follows:
\newcommand\StringCount[2]{\luaexec{
_ , count = string.gsub ( \luastring{#2} , \luastring{#1} , "" )
tex.sprint ( count ) }}
This macro may be used, for instance, as
\StringCount{yes}{a yes b yes c yes desyesfg mess ij}
(result: 4) or as
\StringCount{es}{a yes b mesh c best less xxDavieszz mess ij}
(result: 6).