在正则表达式中使用 xparse 键值存储中的值

在正则表达式中使用 xparse 键值存储中的值

这是上一个问题的延伸(关联)。我想将以下xparse保存值的键值存储包含name到以下文档中:

% Key-value store
\ExplSyntaxOn 

\prop_new:N \list_prop

\keys_define:nn {bio} {%
    name  .code:n={ \prop_put:Nnn \list_prop {name}  {#1} },
}

\NewDocumentCommand{\update}{+m}{%
    \keys_set:nn {bio} {#1}%
}

\cs_new:Npn \getvalue#1{%
    \prop_item:Nn \list_prop {#1}
}

\ExplSyntaxOff

% Default variable values
\update{%
    name={John Doe}
}

我想使用下面定义的存储name来自动更新。换句话说,将根据上述键值存储中的值自动定义。理想的做法是保留该函数以获得灵活性,但在未传递参数时将其设为默认值。l_adam_name_full_tl\adam_name_define:nl_adam_name_full_tl\definename\getvalue{name}

\documentclass{article}

\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\definename}{m}
 {
  \adam_name_define:n { #1 }
 }

\NewDocumentCommand{\makebold}{m}
 {
  \adam_name_makebold:n { #1 }
 }

\tl_new:N \l_adam_name_full_tl
\tl_new:N \l_adam_name_first_tl
\tl_new:N \l_adam_name_last_tl
\tl_new:N \l_adam_name_initials_tl
\tl_new:N \l__adam_name_input_tl

\cs_new_protected:Nn \adam_name_define:n
 {
  \tl_set:Nn \l_adam_name_full_tl { #1 }
  \tl_set_eq:NN \l_adam_name_first_tl \l_adam_name_full_tl
  \tl_set_eq:NN \l_adam_name_last_tl \l_adam_name_full_tl
  \regex_replace_once:nnN { (.*)\s[^\s]*\Z } { \1 } \l_adam_name_first_tl
  \regex_replace_once:nnN { .*\s([^\s]*)\Z } { \1 } \l_adam_name_last_tl
  \tl_set_eq:NN \l_adam_name_initials_tl \l_adam_name_first_tl
  \regex_replace_all:nnN { ([[:alpha:]])[[:alpha:]]+ } { \1. } \l_adam_name_initials_tl
 }

\cs_new_protected:Nn \adam_name_makebold:n
 {
  \tl_set:Nn \l__adam_name_input_tl { #1 }
  % full name
  \regex_replace_once:nnN
   {
    (
     \u{l_adam_name_full_tl}                                   % name surname
     |
     \u{l_adam_name_initials_tl} \s \u{l_adam_name_last_tl}    % initials surname
     |
     \u{l_adam_name_last_tl} , \s \u{l_adam_name_first_tl}     % surname, name
     |
     \u{l_adam_name_last_tl} , \s \u{l_adam_name_initials_tl}  % surname, initials
    )
   }
   { \c{textbf} \cB\{ \1 \cE\} }
   \l__adam_name_input_tl
  % print
  \tl_use:N \l__adam_name_input_tl
 }

\ExplSyntaxOff

\begin{document}

  \definename{John Doe}

  \makebold{His name was John Doe.}

  \makebold{His name was J. Doe.}

  \makebold{His name was Doe, J..}

  \definename{John T. Doe}

  \makebold{His name was John T. Doe.}

  \makebold{His name was J. T. Doe.}

  \makebold{His name was Doe, J. T..}

\end{document}

预期输出:

他以前的名字是约翰·多伊

他以前的名字是多伊,约翰

他以前的名字是J·多伊

他以前的名字是多伊,J.

他以前的名字是约翰·T·多伊

他以前的名字是JT Doe

他以前的名字是多伊,JT

答案1

您可以使用\prop_set_from_keyval:Nn而不是定义键,但这不是重点。

这里我定义了\update填充属性列表,并调用\adam_name_define:x提取name属性。这里你可以看到一个优点expl3:该函数只是\adam_name_define:n它的一个变体,它在执行工作之前会对其参数进行完全扩展。

请参阅其他答案以了解对正则表达式代码的注释。

\documentclass{article}
\usepackage{xparse}

\ExplSyntaxOn

\NewDocumentCommand{\definename}{m}
 {
  \adam_name_define:n { #1 }
 }

\NewDocumentCommand{\makebold}{m}
 {
  \adam_name_makebold:n { #1 }
 }

\NewDocumentCommand{\makeboldlastname}{m}
 {
  \adam_name_makebold_lastname:n { #1 }
 }

\NewDocumentCommand{\update}{m}
 {
  \prop_clear:N \l_adam_name_bio_prop
  \prop_set_from_keyval:Nn \l_adam_name_bio_prop { #1 }
  \adam_name_define:x { \prop_item:Nn \l_adam_name_bio_prop { name } }
 }

\prop_new:N \l_adam_name_bio_prop
\tl_new:N \l_adam_name_full_tl
\tl_new:N \l_adam_name_first_tl
\tl_new:N \l_adam_name_last_tl
\tl_new:N \l_adam_name_initials_tl
\tl_new:N \l__adam_name_input_tl

\cs_new_protected:Nn \adam_name_define:n
 {
  \tl_set:Nn \l_adam_name_full_tl { #1 }
  \tl_set_eq:NN \l_adam_name_first_tl \l_adam_name_full_tl
  \tl_set_eq:NN \l_adam_name_last_tl \l_adam_name_full_tl
  \regex_replace_once:nnN { (.*)\s[^\s]*\Z } { \1 } \l_adam_name_first_tl
  \regex_replace_once:nnN { .*\s([^\s]*)\Z } { \1 } \l_adam_name_last_tl
  \tl_set_eq:NN \l_adam_name_initials_tl \l_adam_name_first_tl
  \regex_replace_all:nnN { ([[:alpha:]])[[:alpha:]]+ } { \1. } \l_adam_name_initials_tl
 }
\cs_generate_variant:Nn \adam_name_define:n { x }

\cs_new_protected:Nn \adam_name_makebold:n
 {
  \tl_set:Nn \l__adam_name_input_tl { #1 }
  % full name
  \regex_replace_once:nnN
   {
    (
     \u{l_adam_name_full_tl}                                   % name surname
     |
     \u{l_adam_name_initials_tl} \s \u{l_adam_name_last_tl}    % initials surname
     |
     \u{l_adam_name_last_tl} , \s \u{l_adam_name_first_tl}     % surname, name
     |
     \u{l_adam_name_last_tl} , \s \u{l_adam_name_initials_tl}  % surname, initials
    )
   }
   { \c{textbf} \cB\{ \1 \cE\} }
   \l__adam_name_input_tl
  % print
  \tl_use:N \l__adam_name_input_tl
 }

\cs_new_protected:Nn \adam_name_makebold_lastname:n
 {
  \tl_set:Nn \l__adam_name_input_tl { #1 }
  \regex_replace_once:nnN
   { (\u{l_adam_name_last_tl}) }
   { \c{textbf} \cB\{ \1 \cE\} }
   \l__adam_name_input_tl
  \tl_use:N \l__adam_name_input_tl
 }

\ExplSyntaxOff

\begin{document}

\update{
  name=John Doe,
  town=London,
  birth=1888-05-01,
}

\makebold{His name was John Doe.}

\makebold{His name was J. Doe.}

\makebold{His name was Doe, John.}

\makebold{His name was Doe, J. again.}

\makeboldlastname{Again, Doe was his last name.}

\makebold{Jackson, Bob and J. Doe.}

\update{
  name=John T. Doe,
  town=New York,
}

\makebold{His name was John T. Doe.}

\makebold{His name was J. T. Doe.}

\makebold{His name was Doe, John T. again.}

\makebold{His name was Doe, J. T. again.}

\makeboldlastname{Again, Doe was his last name.}

\definename{Brutus Cyclops Dull}

\makebold{His name was Brutus Cyclops Dull.}

\makebold{His name was B. C. Dull.}

\makebold{His name was Dull, Brutus Cyclops again.}

\makebold{His name was Dull, B. C. again.}

\makeboldlastname{Again, Dull was his last name.}

\end{document}

在此处输入图片描述

相关内容