# Missing space when replacing with \regex_replace_all:nnN

How can I make \regex_replace_all:nnN not remove the space between x y?

\documentclass{article}
\usepackage{l3regex}

\ExplSyntaxOn
\cs_new:Npn \replace #1#2#3
{
\tl_set:Nn \l_tmpa_tl  {#3}
\regex_replace_all:nnN {#1} {#2} \l_tmpa_tl
\tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff

\begin{document}
\replace{a}{x y}{abc}
\end{document}

-
Spaces are ignored in the first two arguments of \regex_replace_all:nnN; you should use \cS\  for a space –  egreg Jan 24 '13 at 0:28
That works. Thanks. But what would be a more systematic way of doing that? –  nicolai.rostov Jan 24 '13 at 0:37
I guess this is the best method. Making (unescaped) spaces not being ignored would pose very big problems. And you have to take into account that characters in TeX have also a category code. –  egreg Jan 24 '13 at 0:42
I see. The problem is asking users who only know the interface to do that. :) –  nicolai.rostov Jan 24 '13 at 0:44
If the replacement is that simple, you can also use \tl_replace_all:Nnn –  egreg Jan 24 '13 at 0:46

The syntax rules for regex substitutions are rather bizarre under some respects; as the documentation specifies, significant spaces in the search or the replacement strings should always be escaped, because unescaped spaces are ignored.

Moreover you need to specify that you want a "real" space with the right category code; if you simply say x\ y in the replacement string, you'd get a category code 12 space, which would print whatever character is in slot 32 of the current font (which in OT1 encoding is a strange glyph and in T1 encoding, but also in T2A, is a "visible space").

So the most correct syntax would be

\replace{a}{\cLx\cS\ \cLy}{abc}


where you specify that you want x and y as normal letters: by default l3regex uses category code 12 characters. However this is being picky, as category code 12 and 11 characters are indistinguishable when printed.

For simple substitutions like that you could use

\tl_replace:Nnn


So, for example,

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn
\NewDocumentCommand{\replace}{mmm}
{
\tl_set:Nn \l_tmpa_tl {#3}
\tl_replace_all:Nnn \l_tmpa_tl {#1} {#2}
\tl_use:N \l_tmpa_tl
}
\ExplSyntaxOff

\begin{document}
\replace{a}{x y}{abc}
\end{document}

-
Great! Thank you. Is there any way that could also work for \replace{a}{x y}{\textbf{a}bc}? –  nicolai.rostov Jan 24 '13 at 1:08
@nicolai.rostov Sorry, not without regex. –  egreg Jan 24 '13 at 7:31
@egreg: What is the last \l_tmpa_la in the line \tl_replace_all:Nnn \l_tmpa_tl {#1} {#2} \l_tmpa_tl for? As far as I can see it’s no argument of \tl_replace_all:Nnn –  Tobi Dec 26 '13 at 11:48
@Tobi It's a misprint, probably a remains of a previous version of the code. Thanks for noting –  egreg Dec 26 '13 at 11:53
@egreg: Thanks and merry Christmas :-) –  Tobi Dec 26 '13 at 12:14