在 Perl 正则表达式中的枚举中应用项目替换?

在 Perl 正则表达式中的枚举中应用项目替换?

数据

7. Masi is the same as
\begin{enumerate}
A
B
ABC ha lorem
\end{enumerate}

1. ABC is
\begin{enumerate}
P
B
Lorem maam
\end{enumerate}

我想成为

7. Masi is the same as
\begin{enumerate}
\item A
\item B
\item ABC ha lorem
\end{enumerate}

1. ABC is
\begin{enumerate}
\item P
\item B
\item Lorem maam
\end{enumerate}

我的启动正则表达式基于此回答

perl -000pe
s/\n/\n\\begin{enumerate}\n [A-Za-z1-9]* \end{enumerate}/
... [problem here!]
masi.tex

在哪里

  • -000 :激活 Perl 的段落模式,这会导致“行”由两个连续的换行符 (\n\n) 定义,以便您的每个问题都被视为一行。
  • -pe :读取输入文件的每一行并在应用作为 -e 传递的脚本后打印它(-p)。

我想将比赛中每个新行的开头替换为\item.我的伪代码问题在这里代码

s/\n/\项目 /g

在枚举环境中应用事物。

如何

答案1

你可以使用..范围运算符将替换限制在开始/结束部分:

while (<DATA>) {
   if ( /\\begin/ .. /\\end/ ) {
       s/^(?!\\)/\\item /;  
   }
   print;
}

__DATA__
7. Masi is the same as
\begin{enumerate}
A
B
ABC ha lorem
\end{enumerate}

1. ABC is
\begin{enumerate}
P
B
Lorem maam
\end{enumerat

如果您更喜欢命令行脚本:

perl -ne 'if (/\\begin/../\\end/) {s/^(?!\\)/\\item /};print'

或者,用隐式更短print

perl -pe 'if (/\\begin/../\\end/) {s/^(?!\\)/\\item /}'

(?!...)是一个否定的前瞻断言。

答案2

另一个Perl解决方案:

$ perl -pe '
    if (/\\begin/../\\end/) {
        next if /\\begin/ || /\\end/;
        s/^/\\item /;
    }
' file
7. Masi is the same as
\begin{enumerate}
\item A
\item B
\item ABC ha lorem
\end{enumerate}

1. ABC is
\begin{enumerate}
\item P
\item B
\item Lorem maam
\end{enumerate}

解释

  • if (/\\begin/../\\end/):我们的行分隔符以 开始\begin并结束\end
  • next if /\\begin/ || /\\end/:我们不需要开始和结束,跳过它们。
  • s/^/\\item /:我们用我们想要的模式替换每行的开头。
  • -p选项会导致perl在我们处理后打印每一行。

答案3

使用旗帜。进入enumerate时设置为1,最后清零。设置标志时插入项目:

perl -pe '$inside = 0 if /\\end{enumerate}/;
          print "\\item " if $inside;
          $inside = 1 if /\\begin{enumerate}/;
         ' input.tex

请注意,我在打印之前检查了结尾,因此\item不会将其添加到结束行之前。

相关内容