使用正则表达式提取唯一多次出现的两个值(发送到宏变量)

使用正则表达式提取唯一多次出现的两个值(发送到宏变量)

我从一份用西班牙语写的圣经段落文件中读出了一些关键价值观,如下所示

1 Corintios 2:4-5; Mateo 15:1-10;Salmos 118:16

我想提取每个参考文献中的引文(可以是一个或多个),并且对于参考文献中的每个引文,我需要将其拆分以获取“书名”和“章节”,以便将两者发送到特殊索引。书名前面可以加数字。对于每个出现的情况,我想将值“存储”到 l_hpbook 和 l_hpchapter 变量中。我可以使用正确的正则表达式,但无法将值存储在相应的宏变量 lp_hpbook 和 l_hpchapter 中。有什么提示吗?(bibleref 中没有此功能,甚至没有西班牙语包)

\documentclass{article}
\usepackage{expl3}
\usepackage{l3regex}

\ExplSyntaxOn
\tl_new:N \l_hpsplit_tl

\cs_new:Npn \hpsplit #1 {
% Purpose: Extract all words that are followed by a space + number
%          optionally preceded by a number and space
% Return: All matches are stored in a global token \hpmatches_tl
\str_new:N \l_hpbook
\int_new:N \l_hpchapter 

\tl_new:N \l_holdmatches

\int_new:N \l_hpmatch_int
\tl_set:Nn \l_hpsplit_tl {#1}

% This statement DOES NOT work .  Count of matches not stored in variable
% Count \l_hpmatch_int % Output generates error: Missing number
\regex_count:nnN {\d+\s\w+\s\d+|\w+\s\d+ } { #1 } \l_hpmatch_int
%    Count \l_hpmatch_int % Output generates error: Missing number

% Splits multiple citations: book name and chapter number retrieved
% This statement WORKS!
\regex_extract_all:nnN{ \d+\s\w+\s\d+|\w+\s\d+} { #1 } \l_holdmatches%
\seq_map_inline:Nn \l_holdmatches { 
    item:~##1\par% 

    % Extract the book name of a single citation
    \regex_extract_once:nnN{ \d+\s\w+|\w+} { ~##1 } \l_hpbook%
%       \l_hpbook % this one generates error

    % Extract the book's chapter from a single citation
    % by finding the last occurrence of space and digits
    \regex_extract_once:nnN{(?!.*\s\d)\d+} { ~##1 } \l_hpchapter%
%       \l_hpchapter   % this one generates error if uncommented. 

% I want to use these two variables as follows:
% \index{\lp_hpbook!lp_hpchapter!\articlename}
}%

\tl_use:N \l_hpsplit_tl

%    \hpvar{\seq_map_inline:Nn \l_holdmatch {~##1\par }}%
}
\ExplSyntaxOff

\begin{document}
    % Will read several references from book like this
    % Need to obtain 'book name' separate from chapter
    \hpsplit{1 Corintios 2:4-5; Mateo 15:1-10;Salmos 118:16}
 \end{document}

答案1

我认为最好先用分号分割参数,然后从每个项目中提取数据。

\documentclass{article}
\usepackage{xparse,l3regex}

\ExplSyntaxOn
\NewDocumentCommand{\hpsplit}{sm}
 {
  \IfBooleanTF{#1}
   { \hpcolos_hpsplit:V #2 }
   { \hpcolos_hpsplit:n { #2 } }
 }

\seq_new:N \l__hpcolos_hpsplit_seq
\seq_new:N \l__hpcolos_entry_seq

\cs_new_protected:Nn \hpcolos_hpsplit:n
 {
  \seq_set_split:Nnn \l__hpcolos_hpsplit_seq { ; } { #1 }
  \seq_map_function:NN \l__hpcolos_hpsplit_seq \hpcolos_hpentry:n
 }
\cs_generate_variant:Nn \hpcolos_hpsplit:n { V }

\cs_new_protected:Nn \hpcolos_hpentry:n
 {
  \regex_split:nnN { \s* ([0-9]+)[\:0-9-]* \Z } { #1 } \l__hpcolos_entry_seq
  \hpcolos_index_entry:
 }

\cs_new_protected:Nn \hpcolos_index_entry:
 {
  Book~is~``\seq_item:Nn \l__hpcolos_entry_seq { 1 }''
  ---
  Chapter~is~``\seq_item:Nn \l__hpcolos_entry_seq { 2 }''
  \par
 }
\cs_generate_variant:Nn \tl_trim_spaces:n { f }
\ExplSyntaxOff

\begin{document}

\hpsplit{1 Corintios 2:4-5; Mateo 15:1-10;Salmos 118:16}

\end{document}

我定义了最后一个函数\hpcolos_index_entry:来打印数据,请根据您的喜好进行定义。

enter image description here

诀窍是使用\regex_split:nnN根据正则表达式拆分给定的标记列表:捕获组中的匹配部分将被记住,其余部分将被丢弃。因此,第一种情况将设置序列以包含1 Corintios2。 和诗句编号之前的空格2将被删除,因为它们不在捕获组中。

如果您想将宏传递给命令,请使用\hpsplit*{\foo},其中\foo扩展为如上所述的圣经参考列表。

相关内容