EDITAR:Solução paraesseproblema abaixo.
Estou tentando fazer uma substituição direta de palavras inteiras no texto, mas parece que o uso regex_replace_all
não funciona corretamente, pois não encontra uma palavra que termine com ß.
Eu não quero usar "s para ßno texto a ser substituído, embora isso funcione!
Como MWE:
\documentclass{article}
\usepackage[utf8]{inputenc}
\ExplSyntaxOn
\newcommand{\replaceText}[1]{%
\f_replace_text:n { #1 }
}
\tl_new:N \l_replace_text_tl
\tl_new:N \l_replace_a_tl
\tl_new:N \l_replace_b_tl
\cs_new_protected:Npn \f_replace_text:n #1 {%
\tl_set:Nn \l_replace_text_tl { #1 }
\f_replace:
\tl_use:N \l_replace_text_tl
}
\cs_new_protected:Npn \f_replace: {%
%
\tl_set:Nn \l_replace_a_tl { Grieß }
\tl_set:Nn \l_replace_b_tl { Mehl }
\regex_replace_all:nnN { \b\u{l_replace_a_tl}\b } { \u{l_replace_b_tl} } \l_replace_text_tl
%
\tl_set:Nn \l_replace_a_tl { Grießmenge }
\tl_set:Nn \l_replace_b_tl { Mehlmenge }
\regex_replace_all:nnN { \b\u{l_replace_a_tl}\b } { \u{l_replace_b_tl} } \l_replace_text_tl
%
\tl_set:Nn \l_replace_a_tl { some }
\tl_set:Nn \l_replace_b_tl { more }
\regex_replace_all:nnN { \b\u{l_replace_a_tl}\b } { \u{l_replace_b_tl} } \l_replace_text_tl
%
}
\ExplSyntaxOff
\begin{document}
\noindent Writing some text.
\replaceText{Replacing some text.}
\replaceText{Forgetting to replace Grieß.}
\replaceText{But not forgetting to replace Grießmenge.}
\end{document}
Isso produz:
Escrevendo algum texto. Substituindo mais texto. Esquecendo de substituirGriess. Mas não esquecendo de substituir Mehlmenge.
No entanto, eu teria esperado:
Escrevendo algum texto. Substituindo mais texto. Esquecendo de substituirMehl. Mas não esquecendo de substituir Mehlmenge.
Por que isso acontece e como posso evitar que isso aconteça? Eu tentei algumas maneiras de escapar do caractere na regex, mas não consegui fazer funcionar.
EDITAR: Nesse caso, as seguintes adições fazem com que funcione: Substituindo todas as instâncias de ß por suas ligaduras antes de usar os outros comandos regex que usam apenas a ligadura "s (dentro da pesquisa, não necessariamente na substituição) e depois alterando-as de volta em o fim:
\tl_new:N \l_replace_utf_tl
\tl_new:N \l_replace_ligature_tl
\cs_new_protected:Npn \f_replace_text:n #1 {%
\tl_set:Nn \l_replace_text_tl { #1 }
\tl_set:Nn \l_replace_utf_tl { ß }
\tl_set:Nn \l_replace_ligature_tl { "s }
\regex_replace_all:nnN { \u{l_replace_utf_tl} } { \u{l_replace_ligature_tl} } \l_replace_text_tl
\f_replace:
\regex_replace_all:nnN { \u{l_replace_ligature_tl} } { \u{l_replace_utf_tl} } \l_replace_text_tl
\tl_use:N \l_replace_text_tl
}
Responder1
O problema é que para uma correspondência tem que haver um limite de palavra \b
, isso significa uma mudança de \w
-class para \W
ou vice-versa.
Mas l3regex
atualmente não oferece suporte a Unicode completo. A classe \w
contém apenas ascii [A-Za-z0-9\_]
. Isso significa que o ß
(ou mais precisamente os dois bytes que compõem o ß) pertence, \W
assim como o período e, portanto, Grieß.
não corresponde.