是否可以使用 \regex_replace_all 代替 \tl_replace_all

是否可以使用 \regex_replace_all 代替 \tl_replace_all

我有以下宏定义:

\let\hlORIG\hl
\ExplSyntaxOn
\tl_new:N \l_jdhao_hlx_tl
\RenewDocumentCommand\hl{m}{%
  \tl_set:Nn\l_jdhao_hlx_tl{#1}%
  \tl_replace_all:Nnn\l_jdhao_hlx_tl{\ }{~}%
  \tl_replace_all:Nnn\l_jdhao_hlx_tl{-\/-}{\mbox{-\/-}}%
  \tl_replace_all:Nnn\l_jdhao_hlx_tl{,}{,{\-}}% allow line breaking at a comma
  \exp_args:NV\hlORIG\l_jdhao_hlx_tl}%
\ExplSyntaxOff

上面的代码可以进行简单的替换,但我认为我不能进行某些条件替换。例如,我希望能够将前面和后面都是字母数字的连字符替换为相同的字符,只是连字符被替换为\-/(例如,alpha-baker将被更改为alpha\-/baker)。同时,如果连字符中有空格或非字母数字字符,则将保持不变。这可能吗?我希望得到的是不会造成连字符的连字符。我想我可以用\regex_replace_all代替\tl-replace_all。这有意义吗,或者有更好的方法吗?

更新 #1

pdflatex显示的版本信息为:

pdfTeX 3.1415926-2.5-1.40.14 (TeX Live 2013/Debian)
kpathsea version 6.1.1
Copyright 2013 Peter Breitenlohner (eTeX)/Han The Thanh (pdfTeX).
There is NO warranty.  Redistribution of this software is
covered by the terms of both the pdfTeX copyright and
the latest FNU general Public License.
For more information about these matters, see the file
named COPYING and the pdfTeX source.
Primary author of pdfTeX: Peter Breitenlohner (eTeX)/Han The Thanh (pdfTeX).
Compiled with libpng 1.2.49; using libpng 1.2.50
Compiled with zlib 1.2.8; using zlib 1.2.8
Compiled with poppler version 0.24.5

更新 #2

\usepackage{regexpatch}通过添加and/or ,我能够在一定程度上实现这一点\usepackage{l3regex}。现在它可以运行,但输出看起来并不像下面这样。我得到以下内容:

The token list \l_jdb_tl contains the tokens:
> a (the letter a)
> l (the letter l)
> p (the letter p)
> h (the letter h)
> a (the letter a)
> \- (control sequence=macro:->\discretionary {-}{}{})
> / (the character /)
> b (the letter b)
> e (the letter e)
> t (the letter t)
> a (the letter a)
>recently read>}

我不知道为什么我会得到> \- (control sequence=macro:->\discretionary {-}{}{})并且下面是control sequence=macro:->\x@protect \-\protect \-语句。唯一真正的区别是我将 移到regex_const了 中regex_replace_all。可能是版本差异。

最后更新 大家好,我终于能够按照我需要的方式让这一切正常工作,而且比我之前遇到的漏洞要好得多。为了结束这个话题,下面是我用来替换我记录的原始代码的正则表达式代码:

\usepackage{regexpatch}
\let\hlORIG\hl
\ExplSyntaxOn
\regex_const:Nn\c_jdhao_space_regex{\c{\s}}
\regex_const:Nn\c_jdhao_ddash_regex{(\-\c{/}\-)}
\regex_const:Nn\c_jdhao_comma_regex{\,}
\tl_new:N\l_jdhao_hlx_tl
\RenewDocumentCommand\hl{m}{
  \tl_set:Nn\l_jdhao_hlx_tl{#1}
  \regex_replace_all:NnN\c_jdhao_space_regex{\cS\ }\l_jdhao_hlx_tl
  \regex_replace_all:NnN\c_jdhao_ddash_regex{\c{mbox}\cB\{\1\cE\}}\l_jdhao_hlx_tl
  \regex_replace_all:NnN\c_jdhao_comma_regex{,\cB\{\-\cE\}}\l_jdhao_hlx_tl
  \exp_args:NV\hlOrig\l_jdhao_hlx_tl
}

现在,扩展上述内容相对容易,并且知道我可以使用模式来确保在正确的情况下使用替换标记,而旧的宏只是直接“找到这个字符串并用另一个字符串替换它”。

答案1

一个正则表达式取代您在问题中明确提到的情况(字母数字后跟连字符,后跟字母数字,用相同的字母数字字符和\-/中间的 a 替换)。

我使用 预编译了正则表达式\regex_const:Nn,如果要多次使用正则表达式,这应该可以节省一些时间。代码不会产生任何打印输出,只有一些控制台输出:

\documentclass[]{article}

\usepackage{expl3}
\usepackage{xparse}
\ExplSyntaxOn
\regex_const:Nn \c_jonbelanger_regex { ([A-Za-z\d])-([A-Za-z\d]) }
\tl_new:N \l_jonbelanger_tl
\NewDocumentCommand \hyphenthingy { m }
  {
    \tl_set:Nn \l_jonbelanger_tl { #1 }
    \regex_replace_all:NnN \c_jonbelanger_regex { \1\c{-}/\2 } \l_jonbelanger_tl
    \tl_show_analysis:N \l_jonbelanger_tl
  }
\ExplSyntaxOff

\begin{document}
\hyphenthingy{alpha-baker}
\end{document}

以下内容打印到控制台:

The token list \l_jonbelanger_tl contains the tokens:
>  a (the letter a)
>  l (the letter l)
>  p (the letter p)
>  h (the letter h)
>  a (the letter a)
>  \- (control sequence=macro:->\x@protect \-\protect \-  )
>  / (the character /)
>  b (the letter b)
>  a (the letter a)
>  k (the letter k)
>  e (the letter e)
>  r (the letter r).

相关内容