根据前后字符替换字符串中的字符

根据前后字符替换字符串中的字符

以下两个字符串是 biblatex 引用命令扩展的结果:

联通计算机公司(诉讼中),13 F.3d 321, 30 Collier Bankr. Cas. 2d 655, 25 Bankr. Ct. Dec. 152(第九巡回上诉法院 1994 年)

个人财产安全法 (PEI),RSPEI 1988,c. P-3.1

我想要做的是将 biblatex 引用命令包装在一个宏中,该宏将用由以下条件集确定的替换字符替换所有点:

  1. 如果点右边的字符不是数字,则应将点完全删除。

  2. 如果点右边的字符是数字,并且点左边的字符也是数字,则应该用点替换该点,也就是说,点应该保留在原位。

  3. 如果点右边的字符是数字,而点左边的字符不是数字,则应将点替换为空格。

将条件应用到上面的示例字符串上,宏应该产生以下结果:

联通计算机公司(诉讼中),13 F 3d 321, 30 Collier Bankr Cas 2d 655, 25 Bankr Ct Dec 152(第九巡回上诉法院 1994 年)

个人财产安全法 (PEI),RSPEI 1988,c P-3.1

应该注意的是,示例中的点已经在 bibtex 文件的条目中了。之所以有点,是因为某些合法的引用样式需要标点符号,而其他样式则要求标点符号不存在,我正在编写的 biblatex 样式应该有一个选项可以打开或关闭标点符号,而且自动删除点似乎比自动添加点更容易。

我查看了该xstring包,但没能找到合适的宏。此外,我更希望能够在纯 TeX 中执行此操作,这样就可以使用生成的样式而不需要太多依赖项。

答案1

通过一个简单的循环,xstring 还可以做这样的事情:

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{xstring}
\def\removedot#1{%
    \def\citation{#1}%
    \loop
        \StrPosition\citation.[\dotpos]%
        \ifnum\dotpos>0
        \StrMid\citation1{\number\numexpr\dotpos-1}%
        \StrChar\citation{\number\numexpr\dotpos-1}[\antechar]%
        \StrChar\citation{\number\numexpr\dotpos+1}[\postchar]%
        \antechar
        \IfInteger\postchar{\IfInteger\antechar.{\unless\ifx\postchar\space\space\fi}}{}%
        \postchar
        \StrGobbleLeft\citation{\number\numexpr\dotpos+1}[\citation]%
    \repeat
    \citation
}
\begin{document}
\removedot{Unicom Computer Corp. (in re), 13 F.3d 321, 30 Collier Bankr. Cas. 2d 655, 25 Bankr. Ct. Dec. 152 (9th Cir. 1994)\endgraf
Personal Property Security Act (P.E.I.), R.S.P.E.I. 1988, c. P-3.1}
\end{document}

编辑:抱歉,这个错误。以下是修复该错误并将结果存储在宏中的代码\newcitation

\documentclass{article}
\usepackage[utf8]{inputenc}
\usepackage[T1]{fontenc}
\usepackage{xstring}
\def\expaddtocs#1#2{%
    \expandafter\expandafter\expandafter\def\expandafter\expandafter\expandafter
    #1\expandafter\expandafter\expandafter{\expandafter#1#2}}
\def\removedot#1{%
    \def\citation{#1}\def\newcitation{}%
    \loop
        \StrPosition\citation.[\dotpos]%
        \ifnum\dotpos>0
        \StrLeft\citation{\number\numexpr\dotpos-2}[\temp]\expaddtocs\newcitation\temp
        \StrGobbleLeft\citation{\number\numexpr\dotpos-2}[\citation]%
        \StrChar\citation1[\antechar]\expaddtocs\newcitation\antechar
        \StrChar\citation3[\postchar]%
        \IfInteger\postchar
            {\IfInteger\antechar{\expaddtocs\newcitation.}{\unless\ifx\postchar\space\expaddtocs\newcitation\space\fi}}
            \relax
        \StrGobbleLeft\citation2[\citation]%
    \repeat
    \expaddtocs\newcitation\citation
    \newcitation% use the \newcitation macro
}
\begin{document}
\removedot{Unicom Computer Corp. (in re), 13 F.3d 321, 30 Collier Bankr. Cas. 2d 655, 25 Bankr. Ct. Dec. 152 (9th Cir. 1994)\endgraf
Personal Property Security Act (P.E.I.), R.S.P.E.I. 1988, c. P-3.1}
\end{document}

当然,本帖中展示的代码都不是用纯 TeX 宏编写的。这太难了,最好使用一个包,无论是 latex3 解析器还是 xstring,两者都是用纯 TeX 编写的。

答案2

这是一个使用 LaTeX 包(适用于l3regexxparse以及后续的expl3捆绑包2011-10-09)的解决方案。

\RequirePackage{l3regex,xparse}
\ExplSyntaxOn
\tl_new:N \l_removedots_tl
\tl_new:N \l_removedots_str
\DeclareDocumentCommand{\removedots}{+v}
  {
    % Store the verbatim argument into a macro.
    \str_set:Nn \l_removedots_str {#1}

    % Remove all dots followed by a non-digit.
    \regex_replace_all:nnN { \.(\D) } { \1 } \l_removedots_str

    % Replace "non-digit--dot--digit" by "non-digit--space-digit".
    \regex_replace_all:nnN { (\D)\.(\d) } { \1\ \2 } \l_removedots_str

    % Re-tokenize the result, storing it into `\l_removedots_tl`
    \tl_set_rescan:Nno \l_removedots_tl
      {
        \int_set:Nn \tex_newlinechar:D { `\^^M }
        \int_set:Nn \tex_endlinechar:D { `\^^M }
      }
      \l_removedots_str

    % Then simply typeset that, but you could do other things to it.
    \tl_use:N \l_removedots_tl
  }
\ExplSyntaxOff


\documentclass{article}
\begin{document}

\removedots |Unicom Computer Corp. (in re), 13 F.3d 321, 30 Collier Bankr. Cas. 2d 655, 25 Bankr. Ct. Dec. 152 (9th Cir. 1994)

Personal Property Security Act (P.E.I.), R.S.P.E.I. 1988, c. P-3.1|

\end{document}

在引擎盖下,这是在做很多工作量很大,因为 TeX 不太适合正则表达式解析。在 TeX 基元中直接执行相同操作会很困难。

答案3

“自动删除点似乎比自动添加点更容易”

从本质上来说,Tex 已经在对标记进行迭代了。

插入点就变得容易了。

使用 David Carlisle 著名的 zz 宏,

添加点

平均能量损失

\documentclass{article}

\def\zz#1{\def\zzsep{}\zzz#1\relax}
\def\zzz#1{\ifx\relax#1\else\def\zzsep{.}#1\zzsep\expandafter\zzz\fi}

\begin{document}

DLR

\zz{DLR}
\end{document}

我设置zzep\-hyphenchar为空白,以便在较长的中文和日文文本块上快速进行无包装的换行,否则材料会超出页面边缘。

换行符

\documentclass[12pt]{article}

\def\zz#1{\def\zzsep{}\zzz#1\relax}
\def\zzz#1{\ifx\relax#1\else\def\zzsep{\-}#1\zzsep\expandafter\zzz\fi}

\newenvironment{hyphblnk}{%
\let\oldhyphenchar\hyphenchar%
\hyphenchar\font=\string"20}{\let\hyphenchar\oldhyphenchar}

\usepackage{fontspec}
\setmainfont{Noto Serif CJK SC}
\begin{document}

From Wikipedia (article about the solar system):

太陽系是一个受太阳引力约束在一起的行星系统,包括太阳以及直接或间接围绕太阳运动的天体。在直接围绕太阳运动的天体中,最大的八颗被称为行星,其余的天体要比行星小很多,比如矮行星、太阳系小行星和彗星。軌道間接围绕太陽运动的天體是衛星,其中有兩顆比最小的行星水星還要大。

\vskip2em
With line-breaks:

\begin{hyphblnk}
\zz{太陽系是一个受太阳引力约束在一起的行星系统,包括太阳以及直接或间接围绕太阳运动的天体。在直接围绕太阳运动的天体中,最大的八颗被称为行星,其余的天体要比行星小很多,比如矮行星、太阳系小行星和彗星。軌道間接围绕太陽运动的天體是衛星,其中有兩顆比最小的行星水星還要大。}
\end{hyphblnk}

\end{document}

扩展有关使用选项的评论:

一个例子可能有助于我理解使用选项设置的意思。

在这些引文中:

引用示例

案件(完全在脚注中)设置为无点斜体 v、直立当事人名称,只是为了好玩,案件年份最后,美国风格,bib 设置(默认设置,脚注 10;覆盖设置,11),然后是入门级设置,将案件年份放在首位(12)。与非裸露覆盖版本(17)相比,SCC 更倾向于 MNC 样式的裸露(无括号)年份(16)。其他元素也是如此,包括次要材料、参考书目项目分组和标签,无论引文是将案件名称内联打印并在脚注中引用,还是全部内联,还是全部脚注。等等。

事实证明它非常灵活,并且具有开放性。

上述选项如下:

lawrefstyle=caseallbelow, %name and ref in footnote: caseallabove, caseabovebelow, caseallbelow
    party-names-italic=false,%default true
    statute-name-italic=false,%default true
    party-separator-italic=true, %default true
    party-separator-dotted=false, %defau--lt false
    printbib-legal=true, %print a McGill bib: default false; print command = \printbibliographylc
    printbib-aglc=true, %print an AGLC bib: default false; print command = \printbibliographylc
%   print-toc-tos=false, %table of cases and statutes: default true
      allbib-mnc-bare=false, %print MNC squareless: default false = not bare = with square brackets
      allbib-mnc-override=false, %bib option for MNC has priority: default true
      case-year-last=true,

相关内容