Multi-substring replace

The programming layer expl3 of the upcoming LaTeX3 offers a lot of handy functions for such tasks. In expl3 the underscore _ character can be used in macro names. We first allocate a new token list variable

\tl_new:N \l_azor_string_tl

Then we define a code level function, which sets the token list variable to the input string and then replaces the desired substrings.

\cs_new_protected:Npn \azor_replace_norsk:n #1
 {
  \tl_set:Nn \l_azor_string_tl { #1 }
  \tl_replace_all:Nnn \l_azor_string_tl { æ } { za }
  \tl_replace_all:Nnn \l_azor_string_tl { ø } { zb }
  \tl_replace_all:Nnn \l_azor_string_tl { å } { zc }
  \tl_use:N \l_azor_string_tl
 }

In the end we defined a document level function (i.e. the one which is to be used by you in when typing the document), which simply calls the code level function with the appropriate argument.

\NewDocumentCommand \norskletterssub { m }
 {
  \azor_replace_norsk:n { #1 }
 }

(Unfortunately the whole thing is not expandable, i.e. when doing \edef\temp{\norskletterssub{øæå}} the macro \temp will not contain zbzazc, but still \norskletterssub {øæå})

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{xparse}

\ExplSyntaxOn

\tl_new:N \l_azor_string_tl

\cs_new_protected:Npn \azor_replace_norsk:n #1
 {
  \tl_set:Nn \l_azor_string_tl { #1 }
  \tl_replace_all:Nnn \l_azor_string_tl { æ } { za }
  \tl_replace_all:Nnn \l_azor_string_tl { ø } { zb }
  \tl_replace_all:Nnn \l_azor_string_tl { å } { zc }
  \tl_use:N \l_azor_string_tl
 }

\NewDocumentCommand \norskletterssub { m }
 {
  \azor_replace_norsk:n { #1 }
 }

\ExplSyntaxOff

\begin{document}

øæå \norskletterssub{øæå}

\end{document}

enter image description here


While I fully endorse using an expl3 based method, here's how you can do the same with xstring.

  1. You should use the trailing optional argument, not doing \def\strA{\StrSubstitute{...}{...}{...}}

  2. You have to care about not doing unwanted expansion: with the utf8 option, the non ASCII characters are essentially macros, hence \noexpandarg is in order.

Here's the code.

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage{datatool,xparse}
\usepackage{xstring}

\NewDocumentCommand{\norskletterssub}{m}{%
  \saveexpandmode\noexpandarg
  \def\tempstring{#1}%
  \xStrSubstitute{\tempstring}{æ}{za}[\tempstring]%
  \xStrSubstitute{\tempstring}{ø}{zb}[\tempstring]%
  \xStrSubstitute{\tempstring}{å}{zc}[\tempstring]%
  \tempstring
  \restoreexpandmode
}
\newcommand*{\xStrSubstitute}{%
  \expandafter\StrSubstitute\expandafter
}

\begin{document}

\norskletterssub{øæå}

\end{document}

enter image description here

If your aim is to do the substitution for a check such as with \IfStrEq, you can do

\NewDocumentCommand{\IfNorskStrEq}{mmmm}{%
  \saveexpandmode\noexpandarg
  \def\tempstring{#1}%
  \xStrSubstitute{\tempstring}{æ}{za}[\tempstring]%
  \xStrSubstitute{\tempstring}{ø}{zb}[\tempstring]%
  \xStrSubstitute{\tempstring}{å}{zc}[\tempstring]%
  \restoreexpandmode
  \IfStrEq{\tempstring}{#2}{#3}{#4}%
}
\newcommand*{\xStrSubstitute}{%
  \expandafter\StrSubstitute\expandafter
}

Now something like

\IfNorskStrEq{våkne}}{vzckne}{true}{false}

should evaluate to true.