# Unexpanded string replace

This question is related to Carry out substring replacement on variable's contents. Is it possible to perform string replace on an arbitrary string, without expansion? MWE:

\documentclass{article}
\usepackage{xstring}
\begin{document}
\noexpandarg
\StrSubstitute{John \textit{knows} that Mary is a unicorn}{knows}{believes}
\end{document}


With this MWE, nothing is replaced. Desired behaviour is a replacement of \textit{knows} with \textit{believes}, i.e., verbatim, plain replacement. Also, e.g., \StrSubstitute{\textit{knows}}{tex}{latex} should result in \latexit{knows} (i.e., replacement should consider the string as given, without taking any internal semantics into consideration).

A pdflatex solution is preferred (no lua, perl, sed, text editor search and replace). xstring is not required.

By default xstring doesn't look into groups. But you can force it to consider also the text in braces:

\documentclass{article}
\usepackage{xstring}
\begin{document}
\noexpandarg
\StrSubstitute{John {knows} that Mary is a unicorn}{knows}{believes}

\exploregroups
\StrSubstitute{John {knows} that Mary is a unicorn}{knows}{believes}

\StrSubstitute{John \textit{knows} that Mary is a unicorn}{knows}{believes}
\end{document}


Such a simple substitution can be obtained quite easily with l3regex.

\documentclass{article}
\usepackage{xparse,l3regex}

\ExplSyntaxOn
\NewDocumentCommand{\strsubstitute}{ +m m m }
{
\tl_set:Nn \l_marijn_strsubst_tl { #1 }
\regex_replace_all:nnN { #2 } { #3 } \l_marijn_strsubst_tl
\tl_use:N \l_marijn_strsubst_tl
}
\tl_new:N \l_marijn_strsubst_tl
\ExplSyntaxOff

\begin{document}

\strsubstitute{John \textit{knows} that Mary is a unicorn}{knows}{believes}

\strsubstitute{John \textit{knows} that Mary is a unicorn}{\c{textit}}{\c{textbf}}

\end{document}