# \StrSubstitute breaks when an argument contains a MathOperator

I'm using \StrSubstitute from the xstring package, and it appears that the .tex file does not compile if any of the arguments to \StrSubstitute contain math operators that I have declared with \DeclareMathOperator. A minimal failing example:

% mfe.tex
\documentclass{article}
\usepackage{xstring,amsmath}

\DeclareMathOperator{\myop}{MyOp}

\begin{document}
$\StrSubstitute{a(B)}{a}{\myop}$
\end{document}


Running pdflatex mfe.tex fails to produce a .pdf file, with mfe.log stating

! TeX capacity exceeded, sorry [input stack size=5000].
\@spaces ->\space
\space \space \space
l.10 $\StrSubstitute{a(B)}{a}{\myop}$
If you really absolutely need more capacity,
you can ask a wizard to enlarge me.

Here is how much of TeX's memory you used:
1067 strings out of 494953
12733 string characters out of 6180978
173300 words of memory out of 5000000
4419 multiletter control sequences out of 15000+600000
4094 words of font info for 16 fonts, out of 8000000 for 9000
14 hyphenation exceptions out of 8191
5000i,3n,4003p,244b,52s stack positions out of 5000i,500n,10000p,200000b,80000s
!  ==> Fatal error occurred, no output PDF file produced!


By contrast, I can get the output I want by making \myop just use \mathrm. A minimal working example:

% mwe.tex
\documentclass{article}
\usepackage{xstring,amsmath}

\newcommand{\myoprm}{\mathrm{MyOp}}

\begin{document}
$\StrSubstitute{a(B)}{a}{\myoprm}$
\end{document}


Which produces the following output:

Any idea what's going on here, and how I might get \StrSubstitute to cooperate with my operators? I've been given to understand that \DeclareMathOperator{\foo}{foo} is better practice than \newcommand{\foo}{\mathrm{foo}}, but I need these commands to cooperate with \StrSubstitute.

• \StrSubstitute, by default, use \edef on all its arguments and anything defined with \DeclareMathOperator doesn't survive it. As you discovered, \noexpandarg will work. – egreg Sep 4 '18 at 22:47

I found a workaround that works: in the documentation for xstring, it mentions that the commands read their arguments "syntax unit by syntax unit," suggesting that throwing in a \noexpandarg will affect its behavior.

I don't know what the mechanism is here, but the following edit makes mfe.tex work as expected:

% mfe_redeemed.tex
\documentclass{article}
\usepackage{xstring,amsmath}

\DeclareMathOperator{\myop}{MyOp}

\begin{document}
$\noexpandarg\StrSubstitute{a(B)}{a}{\myop}$
\end{document}


which produces the following output: