
Ich habe eine durch Kommas getrennte Liste von key=value
Zeichenfolgen. Ich möchte den Wert basierend auf dem Schlüssel extrahieren. Etwas in der Art
\LookUpValue{c}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
Dies soll zu der Zeichenfolge führen baz
.
Wie kann ich das machen?
Antwort1
Sie könnten einen benutzerdefinierten Schlüssel-Wert-Parser definieren (vorausgesetzt, der Schlüsselsatz sollte variabel sein):
\documentclass{article}
\makeatletter
\def\LookUpValue#1#2#3{%
\@tempswafalse
\gdef\LookUpValue@false{#3}%
\xdef\@tempa{#1}%
\LookUpValue@#2,\@end,}
\def\LookUpValue@#1,{%
\ifx#1\@end
\if@tempswa\@tempc\else\LookUpValue@false\fi
\else
\LookUpValue@@#1\@nil\expandafter\LookUpValue@\fi}
\def\LookUpValue@@#1=#2\@nil{%
\edef\@tempb{#1}%
\ifx\@tempa\@tempb\gdef\@tempc{#2}\@tempswatrue\fi
}
\makeatother
\begin{document}
\LookUpValue{c}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
\textit{\LookUpValue{d}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}}
\LookUpValue{e}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
\end{document}
Nachtrag I
Wenn Sie sich die Antwort von @egreg ansehen, finden Sie diese sehr nette Funktion, mit der Sie das Ergebnis \LookUpValue
in einem Makro speichern können, ohne es auszudrucken. Hier ist eine Möglichkeit, dies in LaTeX2e zu erreichen (auf Grundlage meiner Hauptlösung):
\documentclass{article}
\makeatletter
\def\LookUpValue{\kernel@ifnextchar[\@LookUpValue{\@LookUpValue[\@tempa]}}
\def\@LookUpValue[#1]#2#3{%
\@tempswafalse
\begingroup
\escapechar\m@ne
\xdef\luv@namespace{\string#1}%
\endgroup
\xdef\reserved@a{#2}%
\expandafter\LookUpValue@#3,\@end,}
\def\LookUpValue@#1,{%
\ifx#1\@end
\if@tempswa\@nameuse{@tempa}\let\@tempa\relax
\expandafter\expandafter\expandafter\@gobble\fi%
\else
\LookUpValue@@#1\@nil\expandafter\LookUpValue@\fi}
\def\LookUpValue@@#1=#2\@nil{%
\edef\reserved@b{#1}%
\ifx\reserved@a\reserved@b\@namedef{\luv@namespace}{#2}\@tempswatrue\fi
}
\makeatother
\begin{document}
\LookUpValue{c}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
\def\mypreset{a=foo,b=bar,c=baz,d=zyyzx}
\LookUpValue[\myval]{d}{\mypreset}{}
\LookUpValue{e}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
\textsc{\myval}
\end{document}
Nachtrag II
Wenn jedoch der Schlüsselsatz, dessen Werte Sie extrahieren möchten, in Ihrem gesamten Dokument unverändert ist, gibt es diesen einfacheren Weg:
\documentclass{article}
\usepackage{keyval}
\makeatletter
\newcommand\newspraffkey[1]{\define@key{spraffkeys}{#1}{\@namedef{value_of_#1}{##1}}}
\newcommand\LookUpValue[2]{%
\begingroup
\setkeys{spraffkeys}{#2}%
\@nameuse{value_of_#1}%
\expandafter\ifx\csname value_of_#1\endcsname\relax\else\expandafter\@gobbleaftergroup\fi
\endgroup
}
\def\@gobbleaftergroup{\aftergroup\@gobble}
\makeatother
\newspraffkey{a}
\newspraffkey{b}
\newspraffkey{c}
\newspraffkey{d}
\begin{document}
\LookUpValue{c}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
\LookUpValue{d}{a=foo,b=bar,c=baz}{error:notfound}
\LookUpValue{e}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
\end{document}
Antwort2
property
Eine Variante, bei der eine Liste mit Syntax ausgefüllt expl3
und nach dem entsprechenden Schlüssel-Wert-Paar gesucht wird. Vielleicht nicht der schnellste Weg, aber recht einfach zu verwenden.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\cs_generate_variant:Nn \prop_put:Nnn {Nxn,Nxx}
\NewDocumentCommand{\LookUpValue}{mmm}{%
\seq_set_from_clist:Nn \l_tmpa_seq {#2}
\seq_map_inline:Nn \l_tmpa_seq {% Mapping through the sequence
\seq_set_split:Nnn \l_tmpb_seq {=} {##1}
% Filling the property list
\prop_put:Nxx \l_tmpa_prop {\seq_item:Nn \l_tmpb_seq {1}} {\seq_item:Nn \l_tmpb_seq {2}}
}
% Look if #1 is in the property list and display the value, otherwise #3
\prop_if_in:NnTF \l_tmpa_prop {#1} {\prop_item:Nn \l_tmpa_prop {#1}} {#3}
}
\ExplSyntaxOff
\begin{document}
\LookUpValue{c}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
\LookUpValue{foobar}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
\end{document}
Antwort3
Der folgende Code verwendet die Schlüssel-Wert-Funktionen in expl3
; hier nutze ich „unbekannte Schlüssel“ aus, es lässt sich etwas Besseres erreichen, wenn die Schlüssel im Voraus bekannt sind.
Wenn ein optionales Argument angegeben wird, sollte es eine Steuersequenz sein, die für das Ergebnis (neu) definiert wird.
\documentclass{article}
\usepackage{xparse}
\ExplSyntaxOn
\NewDocumentCommand{\LookUpValue}{ommm}
{
\str_set:Nn \l_spraff_given_key_str { #2 }
\tl_clear:N \l_spraff_output_tl
\keys_set:nn { spraff/random } { #3 }
\tl_if_empty:NT \l_spraff_output_tl
{
\tl_set:Nn \l_spraff_output_tl { #4 }
}
\IfNoValueTF{#1}
{ \tl_use:N \l_spraff_output_tl }
{ \tl_set_eq:NN #1 \l_spraff_output_tl }
}
\keys_define:nn { spraff/random }
{
unknown .code:n =
\str_if_eq:NNT \l_spraff_given_key_str \l_keys_key_tl
{
\tl_set:Nn \l_spraff_output_tl { #1 }
}
}
\ExplSyntaxOff
\begin{document}
\LookUpValue{c}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
\LookUpValue{e}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
\LookUpValue[\temp]{a}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
\texttt{\meaning\temp}
\end{document}