# Replacing strings including colon by latex3

I would like to replace such as :a into à. The following is the code

\ExplSyntaxOn
\str_new:N \replace_str
\cs_new:Npn \my_replace:n #1
{
\str_set:Nn \replace_str {#1}
\str_replace_all:Nnn \replace_str { :a } { à }
\str_use:N \replace_str
}

\NewDocumentCommand \replace { m }
{
\my_replace:n { #1 }
}
\ExplSyntaxOff


Though this can show à, even control sequences are dealt as strings. Then I used \tl_ instead of \str_.

\ExplSyntaxOn
\tl_new:N \replace_str
\cs_new:Npn \my_replace:n #1
{
\tl_set:Nn \replace_str {#1}
\tl_replace_all:Nnn \replace_str { :a } { à }
\tl_use:N \replace_str
}

\NewDocumentCommand \replace { m }
{
\my_replace:n { #1 }
}


However, it does not show à but :a.

How can I get à with dealing control sequences as so.

• please fix your examples so that people can run them and debug the issue, they are just fragments currently that can't be run and don't have an example of the command being called – David Carlisle Jun 12 '18 at 17:28

The problem are catcodes: Between \ExplSyntaxOn and \ExplSyntaxOff, the catcode of : is 'letter' instead of 'other'. The tl functions differentiate between catcodes, so the colon in the code block is different from the colon in the rest of the document. Happily a colon with catcode 'other' is saved in \c_colon_str, so this can be used instead. Of course, \c_colon_str has to be expanded, so we use \tl_replace_all:Nfn:

\documentclass{article}
\usepackage{xparse,expl3}
\ExplSyntaxOn
\tl_new:N \l_replace_tl
\cs_generate_variant:Nn \tl_replace_all:Nnn { Nfn }
\cs_new:Npn \my_replace:n #1
{
\tl_set:Nn \l_replace_tl {#1}
\tl_replace_all:Nfn \l_replace_tl { \c_colon_str a } { à }
\tl_use:N \l_replace_tl
}

\NewDocumentCommand \replace { m }
{
\my_replace:n { #1 }
}
\ExplSyntaxOff
\begin{document}
\replace{abc:abc\LaTeXe}
\end{document}


I also replaced \replace_tl with \l_replace_tl because variables in expl3 always come with a scope prefix, here it is l_ for local.