
쉼표로 구분된 문자열 목록이 있습니다 key=value
. 키를 기반으로 값을 추출하고 싶습니다. 뭔가 좀 비슷함
\LookUpValue{c}{a=foo,b=bar,c=baz,d=zyyzx}{error:notfound}
의도는 이것이 문자열이 되는 것입니다 baz
.
어떻게 해야 하나요?
답변1
사용자 정의 키-값 파서를 정의할 수 있습니다(키 세트가 가변적이어야 한다고 가정).
\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}
부록 I
@egreg의 답변을 보면 결과를 \LookUpValue
인쇄하지 않고도 매크로에 저장할 수 있는 매우 멋진 기능이 있습니다. LaTeX2e에서 이를 달성하는 방법은 다음과 같습니다(내 주요 솔루션 제공).
\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}
부록 II
그러나 추출하려는 값의 키 세트가 문서 전체에 고정되어 있는 경우 다음과 같은 더 간단한 방법이 있습니다.
\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}
답변2
property
구문을 사용하여 목록을 채우고 expl3
관련 키-값 쌍을 찾는 버전입니다 . 아마도 가장 빠른 방법은 아니지만 사용하기 매우 쉽습니다.
\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}
답변3
다음 코드는 의 키-값 함수를 사용합니다 expl3
. 여기서는 "알 수 없는 키"를 활용합니다. 키를 미리 알고 있으면 더 나은 작업을 수행할 수 있습니다.
선택적 인수가 제공되면 결과에 (재)정의되는 제어 시퀀스여야 합니다.
\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}