Macros – Command to Replace All Occurrences of a Character

macros

How to define a command which replaces every instance of a certain character in its argument with another certain character?

For example, I'd like to define the command \myreplace{1-2-abc-345} which gives me the output 1.2.abc.345 by replacing every - with ..

Best Answer

Use expl3:

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\myreplace}{m}
 {
  \tl_set:Nn \l__maxd_argument_tl { #1 }
  \tl_replace_all:Nnn \l__maxd_argument_tl { - } { . }
  \tl_use:N \l__maxd_argument_tl
 }
\tl_new:N \l__maxd_argument_tl
\ExplSyntaxOff

\begin{document}

\myreplace{1-2-abc-345}

\end{document}

enter image description here

What's the advantage? You can easily generalize your command using the same idea.

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\myreplace}{ O{} m }
 {
  \maxd_replace:nn { #1 } { #2 }
 }

\tl_new:N \l__maxd_argument_tl
\cs_new_protected:Npn \maxd_replace:nn #1 #2
 {
  \group_begin:
  \tl_set:Nn \l__maxd_argument_tl { #2 }
  \keys_set:nn { maxd/replace } { #1 }
  \tl_replace_all:NVV \l__maxd_argument_tl \l_maxd_search_tl \l_maxd_replace_tl
  \tl_use:N \l__maxd_argument_tl
  \group_end:
 }
\cs_generate_variant:Nn \tl_replace_all:Nnn { NVV }

\keys_define:nn { maxd/replace }
 {
  search .tl_set:N = \l_maxd_search_tl,
  search .initial:n = { - },
  replace .tl_set:N = \l_maxd_replace_tl,
  replace .initial:n = { . }
 }

\ExplSyntaxOff

\begin{document}

\myreplace{1-2-abc-345}

\myreplace[replace=--]{1-2-abc-345}

\myreplace[search=2,replace=0]{1-2-abc-345}

\end{document}

enter image description here

Related Question