expl3 の regex_replace_all はドイツ語の ß で問題があります。なぜでしょうか?

expl3 の regex_replace_all はドイツ語の ß で問題があります。なぜでしょうか?

編集:ソリューションこれ問題は下記にあります。

テキスト内で単語全体を直接置換しようとしていますが、regex_replace_allß で終わる単語が見つからないため、使用が正しく機能しないようです。

ßの代わりに「s」を使いたくない置換するテキスト自体ただし、それは機能します。

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}

これにより、次のものが生成されます。

テキストを書いています。さらにテキストを置き換えています。置き換えを忘れていますグリースしかし、メルメンゲの交代も忘れない。

しかし、私は次のように予想していました。

テキストを書いています。さらにテキストを置き換えています。置き換えを忘れていますメールしかし、メルメンゲの交代も忘れない。

なぜそうなるのでしょうか。また、それを防ぐにはどうすればよいのでしょうか。正規表現内の文字をエスケープする方法をいくつか試しましたが、うまくいきませんでした。

編集: この場合、次の追加により機能します: 他の正規表現コマンドを使用する前に、ß のすべてのインスタンスをその合字 "s に置き換えます。これにより、"s 合字のみが使用されます (検索内、必ずしも置換内ではありません)。最後に、それらを元に戻します。

\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
}

答え1

問題は、一致するためには単語境界が必要であり、それは-class\bから への変更、またはその逆の変更を意味することです。\w\W

ただし、l3regex現在は完全な Unicode をサポートしていません。クラス\wには ascii のみが含まれて[A-Za-z0-9\_]います。つまり、ß(より正確には、ß を構成する 2 バイト) は に属し\W、ピリオドも に属しているため、Grieß.一致しません。

関連情報