How to replace text

I'd like to write something like this:

\replace{Text should be replaced here, here and here}{here}{Latex}


It should output

Text should be replaced Latex, Latex and Latex

How can this be done?

• Welcome to TeX.SX! What about there? Should here be replaced too, to give tLatex? – egreg Nov 25 '14 at 16:19
• There are probably more than one approach for this. – user31729 Nov 25 '14 at 16:22
• @egreg In my case I will be replacing a keyword that doesn't occur in arbitrary text, so it doesn't matter. – Marian Nov 25 '14 at 16:22
• @egreg Updated the question. I'm looking for a way to replace 'eqn' and 'eqn.' (and 'eqn,') – Marian Nov 25 '14 at 17:29
• @Marian You may ask a new question about your real problem; I believe there are better ways to deal with it. – egreg Nov 25 '14 at 20:57

A complex solution that only replaces complete words:

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

\ExplSyntaxOn
\NewDocumentCommand{\replace}{mmm}
{
\marian_replace:nnn {#1} {#2} {#3}
}

\tl_new:N \l_marian_input_text_tl
\tl_new:N \l_marian_search_tl
\tl_new:N \l_marian_replace_tl

\cs_new_protected:Npn \marian_replace:nnn #1 #2 #3
{
\tl_set:Nn \l_marian_input_text_tl { #1 }
\tl_set:Nn \l_marian_search_tl { #2 }
\tl_set:Nn \l_marian_replace_tl { #3 }
\regex_replace_all:nnN { \b\u{l_marian_search_tl}\b } { \u{l_marian_replace_tl} } \l_marian_input_text_tl
\tl_use:N \l_marian_input_text_tl
}
\ExplSyntaxOff

\begin{document}

\replace{Text should be replaced here, here and here}{here}{\LaTeX{}}

\replace{Text should be replaced here, here and not there}{here}{\LaTeX{}}

\end{document}


A simpler solution that replaces all occurrences:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\replace}{mmm}
{
\marian_replace:nnn {#1} {#2} {#3}
}

\tl_new:N \l_marian_input_text_tl

\cs_new_protected:Npn \marian_replace:nnn #1 #2 #3
{
\tl_set:Nn \l_marian_input_text_tl { #1 }
\tl_replace_all:Nnn \l_marian_input_text_tl { #2 } { #3 }
\tl_use:N \l_marian_input_text_tl
}
\ExplSyntaxOff

\begin{document}

\replace{Text should be replaced here, here and here}{here}{\LaTeX{}}

\replace{Text should be replaced here, here and not there}{here}{\LaTeX{}}

\end{document}


• Thank you. Do you know a way to replace this: \replace{\replace{start}{start}{fail}}{fail}{success}\\ \replace{fail,}{fail,}{success} – Marian Nov 25 '14 at 17:14
• @Marian - I've provided an answer that sets up the macro \replace so that the result of \replace{\replace{start}{start}{fail}}{fail}{success} is correct, viz., "success". – Mico Nov 25 '14 at 20:48

\def\replace#1#2#3{%
\def\tmp##1#2{##1#3\tmp}%
\tmp#1\stopreplace#2\stopreplace}
\def\stopreplace#1\stopreplace{}

\replace{Text should be replaced here, here and here}{here}{Latex}

\bye


written as plain tex but would work in latex too.

• This is very elegant and the best answer here, congratulations. Unfortunately it is impossible to use such replacing on the token strings when we needn't to expand the tokens. – wipet Dec 3 '14 at 19:14

This uses the higher-level macro StrSubstitute from xstring package. Use [0] as first optional parameter to replace all occurences of here, but as egreg stated in a comment, it will also replace in words like where or there

\documentclass{article}

\usepackage{xstring}

\begin{document}

\StrSubstitute[0]{Text should be replaced here, here and here}{here}{Latex}
\end{document}


Here's a LuaLaTeX-based solution. It uses Lua's powerful string.gsub function in the definition of the \replace macro. The macro \replace can be used recursively.

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode} % for luacode environment and \luastring macro

%% Lua-side code
\begin{luacode}
function myreplace(s,a,b)
x = string.gsub(s,a,b)
tex.sprint ( x )
end
\end{luacode}

%% TeX-side code
\newcommand\replace[3]{\directlua{%
myreplace( \luastring{#1}, \luastring{#2}, \luastring{#3} ) }}

\begin{document}
\replace{Text should be replaced here, here and here.}{here}{Latex}

\replace{\replace{start}{start}{fail}}{fail}{success}

\replace{fail,}{fail,}{success}
\end{document}


Addendum to address the follow-up query by @user61681: If you must replace every single instance of "here" with "LaTeX" in the entire document, and if you can't do so by performing a global search-and-replace operation in your text editor, the following approach may be of interest. It "works" by (a) setting up a Lua function that employs the string.gsub function to replace all instances of "here" with "LaTeX" and (b) assigning this Lua function to LuaTeX's process_input_buffer callback, in effect making it act like a preprocessor on the input stream before TeX starts doing any of its usual work.

Note that this approach will fail is your document contains macros or labels that contain the string here.

% !TEX TS-program = lualatex
\documentclass{article}
\usepackage{luacode}
\begin{luacode}
function myreplace ( s )
s = s:gsub ( "here" , "LaTeX" )
return s
end
\end{luacode}