The following implements this in L3 using etl. It does use the required argument in brackets of your question, though I strongly advice against it. Using non-standard arguments is discouraged for a reason, [] is usually an optional argument, which this isn't, and I see no good reason for the parsing overhead here.
Things to mention:
- this assumes you want to actually count occurences in a token list (no stringification)
- this assumes separators inside braces are to be counted (if not change the nested
+ \vincent_count_tokens_in:nn to \use_none:nn)
- This counts correctly if one of the specified separators is a space
- This doesn't work for non-ASCII separator-symbols in non-UTF8-engines (pdfTeX), otherwise it works in all engine
\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}
Aside: This is not particularly fast, as etl has to check for spaces and groups for each list element, so it does much more in the background than the solution by @StevenB.Segletes, this is only needed if you really want to be able to count spaces, and/or recurse into groups.
\countsep[+]{a\+b}0 or 1)? What about things nested inside braces (is\countsep[+]{a+b{+c}}1 or 2)? – Skillmon Feb 05 '24 at 08:14