在 expl3 案例函数中查找字符串并将结果存储在整型变量中

在 expl3 案例函数中查找字符串并将结果存储在整型变量中

如果我将时区(例如 CEST)传递给函数\__mildate_parse_timezone:n,则函数\__mildate_timezone_abbrev:n应该在 UTC 中找到相关的时区作为整数(用于将来的计算),并且函数\__mildate_timezone_nato:n应该将相关的 NATO 代码输出为字符串。

函数\__mildate_timezone_abbrev:n找到匹配的字符串,但不将其存储在变量中\__mildate_timezone_int

\documentclass[a4paper,10pt]{article}
\usepackage{fontspec}
\usepackage{xparse}

\ExplSyntaxOn

\int_new:N \__mildate_timezone_int
\tl_new:N  \__mildate_timezone_tl

% Time zone NATO code according to UTC
\cs_new_protected:Npn \__mildate_timezone_nato:n #1 {
    \tl_set:Nn \__mildate_timezone_tl {
    \int_case:nnF { #1 }
      {
        { -12 } { Y }    
        { -11 } { X }    
        { -10 } { W }
        { -9 }  { V }   
        { -8 }  { U }   
        { -7 }  { T }
        { -6 }  { S }    
        { -5 }  { R }   
        { -4 }  { Q }   
        { -3 }  { P }   
        { -2 }  { O } 
        { -1 }  { N } 
        { 0 }   { Z }  
        { 1 }   { A }    
        { 2 }   { B }    
        { 3 }   { C }
        { 4 }   { D }   
        { 5 }   { E }   
        { 6 }   { F }
        { 7 }   { G }    
        { 8 }   { H }   
        { 9 }   { I }   
        { 10 }  { K }
        { 11 }  { L }       
        { 12 }  { M } 
      } { ??? }
   }
}

% Abbrev. timezones and their UTC
\cs_new_protected:Npn \__mildate_timezone_abbrev:n #1 {
    % I guess here is the problem!!!
    \int_set:Nn \__mildate_timezone_int {
    \str_case:nnF { #1 }
      {
        { PST }  { -8 }  % Pacific Standard Time
        { PDT }  { -7 }  % Pacific Daylight Time
        { CST }  { -6 }  % Central Standard Time
        { MDT }  { -6 }  % Mountain Daylight Time
        { CDT }  { -5 }  % Central Daylight Time
        { EST }  { -5 }  % Eastern Standard Time
        { GMT }  { 0 }   % Greenwich Mean Time
        { UTC }  { 0 }   % Universal Time Coordinated
        { WET }  { 0 }   % Western European Time
        { CET }  { +1 }  % Central European Time
        { WEST } { +1 }  % Western European Summer Time
        { CEST } { +2 }  % Central European Summer Time
        { EET }  { +2 }  % Eastern European Time
        { EEST } { +3 }  % Eastern European Summer Time
        { TRT }  { +3 }  % Turkey Time
      } { 13 }
   }
}

\seq_new:N \l__mildate_timezone_seq
\cs_new_protected:Npn \__mildate_parse_timezone:n #1 {
    \IfValueT {#1} {
        \regex_match:nnT { \A [a-zA-Z]{2,5} \Z } { #1 }
            { 
                \regex_extract_once:nnN { \A ([a-zA-Z]{2,5}) \Z } { #1 } \__mildate_timezone_seq
                \__mildate_timezone_abbrev:n { \seq_item:Nn \__mildate_timezone_seq {2} }
                \__mildate_timezone_nato:n { \__mildate_timezone_int }
            }
    }
}

\NewDocumentCommand\timezone {m} {
    \__mildate_parse_timezone:n { #1 }
    \__mildate_timezone_tl
}

\ExplSyntaxOff

\begin{document}
    \timezone{CEST}
\end{document}

我需要有人给我指明正确的方向

谢谢,亚历克斯

答案1

我添加了必要的扩展,以便\str_case:nnF比较正确的东西。 也更改\tl_set:Nn为。\tl_set:Nx\__mildate_timezone_nato:n

您应该改为\regex_match:nnT ... \regex_extract_once:nnN\regex_extract_once:nnNT否则,您将对正则表达式进行两次评估,而正则表达式 latex3 已经很慢了。

\documentclass[a4paper,10pt]{article}
\usepackage{fontspec}
\usepackage{xparse}

\ExplSyntaxOn

\int_new:N \__mildate_timezone_int
\tl_new:N  \__mildate_timezone_tl

% Time zone NATO code according to UTC
\cs_new_protected:Npn \__mildate_timezone_nato:n #1 {
    \tl_set:Nx \__mildate_timezone_tl {
        \int_case:nnF { #1 }
        {
            { -12 } { Y }    
            { -11 } { X }    
            { -10 } { W }
            { -9 }  { V }   
            { -8 }  { U }   
            { -7 }  { T }
            { -6 }  { S }    
            { -5 }  { R }   
            { -4 }  { Q }   
            { -3 }  { P }   
            { -2 }  { O } 
            { -1 }  { N } 
            { 0 }   { Z }  
            { 1 }   { A }    
            { 2 }   { B }    
            { 3 }   { C }
            { 4 }   { D }   
            { 5 }   { E }   
            { 6 }   { F }
            { 7 }   { G }    
            { 8 }   { H }   
            { 9 }   { I }   
            { 10 }  { K }
            { 11 }  { L }       
            { 12 }  { M } 
        } { ??? }
    }
}
\cs_generate_variant:Nn \__mildate_timezone_nato:n { V }

% Abbrev. timezones and their UTC
\cs_new_protected:Npn \__mildate_timezone_abbrev:n #1 {
    % I guess here is the problem!!!
    \int_set:Nn \__mildate_timezone_int {
        \str_case:nnF { #1 }
        {
            { PST }  { -8 }  % Pacific Standard Time
            { PDT }  { -7 }  % Pacific Daylight Time
            { CST }  { -6 }  % Central Standard Time
            { MDT }  { -6 }  % Mountain Daylight Time
            { CDT }  { -5 }  % Central Daylight Time
            { EST }  { -5 }  % Eastern Standard Time
            { GMT }  { 0 }   % Greenwich Mean Time
            { UTC }  { 0 }   % Universal Time Coordinated
            { WET }  { 0 }   % Western European Time
            { CET }  { +1 }  % Central European Time
            { WEST } { +1 }  % Western European Summer Time
            { CEST } { +2 }  % Central European Summer Time
            { EET }  { +2 }  % Eastern European Time
            { EEST } { +3 }  % Eastern European Summer Time
            { TRT }  { +3 }  % Turkey Time
        } { 13 }
    }
}
\cs_generate_variant:Nn \__mildate_timezone_abbrev:n { x }

\seq_new:N \l__mildate_timezone_seq
\cs_new_protected:Npn \__mildate_parse_timezone:n #1 {
    \IfValueT {#1} {
        \regex_match:nnT { \A [a-zA-Z]{2,5} \Z } { #1 }
        { 
            \regex_extract_once:nnN { \A ([a-zA-Z]{2,5}) \Z } { #1 } \__mildate_timezone_seq
            \__mildate_timezone_abbrev:x { \seq_item:Nn \__mildate_timezone_seq {2} }
            \__mildate_timezone_nato:V \__mildate_timezone_int
        }
    }
}

\NewDocumentCommand\timezone {m} {
    \__mildate_parse_timezone:n { #1 }
    \__mildate_timezone_tl
}

\ExplSyntaxOff

\begin{document}
    \timezone{CEST}
\end{document}

编辑:我可能会写这个。我不知道你为什么需要使用正则表达式

\NewDocumentCommand\timezone {m} {
    \IfValueT{#1} % Can be removed
    { \__mildate_parse_timezone:n { #1 } } % can be removed
    % \__mildate_parse_timezone:n { #1 } % And use this instead
    \tl_use:N \__mildate_timezone_tl
}
\cs_new_protected:Npn \__mildate_parse_timezone:n #1
{
    \__mildate_timezone_abbrev:x {#1}
    \__mildate_timezone_nato:V \__mildate_timezone_int
}

相关内容