如何仅在某些LaTeX命令参数的范围内进行替换?

时间:2017-07-05 12:45:52

标签: ruby regex perl latex

下面的Latex写在一行中,但可能已经过了几行。

问题是#必须转义字幕命令,所以问题是如何只在字幕内执行此操作?

或者是否存在可以在如此复杂的情况下找到结束}的Perl / Ruby模块?

  

\caption{\small{Et elliptisk område i planen er afgrænset af en ellipse som er niveaukurven $\mathcal{K }_{0}(f)$ for andengradspolynomiet $f(x,y) = 2\cdot x^{2} + 2\cdot y^{2} + 2\cdot x\cdot y -8\cdot x -10 \cdot y + 13$. Se opgave \ref{exercEllipseLevel} og eksempel \href{./20-Keglesnit.pdf#evncount.20.1}{ 20.1} i eNote \ref{tn20}.}} \label{figEllipseLevel}

3 个答案:

答案 0 :(得分:2)

这是Ruby中的一个强力解决方案,现在您已经添加了Ruby标记。它效率不高,但安全而简单。

x.split('\caption').each_with_index.map { |str, i|
  next str if i == 0
  indent = 0
  end_caption = str.length
  str.split('').each_with_index do |c, ci|
    if c == '{'
      indent = indent + 1
    elsif c == '}'
      indent = indent - 1
      if (indent == 0)
        end_caption = ci
        break
      end
    end
  end
  str[0..(end_caption)].gsub(/([^\\])#/,'\1\\#')+ str[(end_caption+1)..-1]
}.join(‘\caption')

或者如果您正在寻找单行,那么

x.gsub(/\\caption\{((?:[^{}]+|\{\g<1>\})+)\}/m)  { |xx| Regexp.last_match[0].gsub(/([^\\])#/,’\1\\#’) }

所有这些当然要求您的Latex文件可以编译。

对于Perl,您可以考虑Text::Balanced

答案 1 :(得分:2)

这可以在Perl中使用两个替换来完成:第一个找到\caption元素,结束第二个替换找到的元素中的所有哈希符号#

使用Regexp::Common::balanced来匹配所需的平衡大括号

是很方便的

此程序的输出显示编辑前后的字符串。它不是最好的测试数据,因为只有一个哈希符号实例,而且没有\caption元素之外的实例,但它确实表明它可以用于示例数据

use strict;
use warnings 'all';
use feature 'say';

use Regexp::Common 'balanced';

my $latex = <<'END';
\caption{\small{Et elliptisk område i planen er afgrænset af en ellipse som er niveaukurven $\mathcal{K }_{0}(f)$ for andengradspolynomiet $f(x,y) = 2\cdot x^{2} + 2\cdot y^{2} + 2\cdot x\cdot y -8\cdot x -10 \cdot y + 13$. Se opgave \ref{exercEllipseLevel}  og  eksempel \href{./20-Keglesnit.pdf#evncount.20.1}{ 20.1} i eNote \ref{tn20}.}} \label{figEllipseLevel}
END

say $latex;

$latex =~ s{ ( \\caption $RE{balanced}{-parens=>'{}'} ) }{
    $1 =~ s/#/\\#/gr;
}xeg;

say $latex;

输出

\caption{\small{Et elliptisk område i planen er afgrænset af en ellipse som er niveaukurven $\mathcal{K }_{0}(f)$ for andengradspolynomiet $f(x,y) = 2\cdot x^{2} + 2\cdot y^{2} + 2\cdot x\cdot y -8\cdot x -10 \cdot y + 13$. Se opgave \ref{exercEllipseLevel}  og  eksempel \href{./20-Keglesnit.pdf#evncount.20.1}{ 20.1} i eNote \ref{tn20}.}} \label{figEllipseLevel}

\caption{\small{Et elliptisk område i planen er afgrænset af en ellipse som er niveaukurven $\mathcal{K }_{0}(f)$ for andengradspolynomiet $f(x,y) = 2\cdot x^{2} + 2\cdot y^{2} + 2\cdot x\cdot y -8\cdot x -10 \cdot y + 13$. Se opgave \ref{exercEllipseLevel}  og  eksempel \href{./20-Keglesnit.pdf\#evncount.20.1}{ 20.1} i eNote \ref{tn20}.}} \label{figEllipseLevel}

答案 2 :(得分:1)

  

试试这个:

my $str = '\caption{\small{Et elliptisk område i planen er afgrænset af en ellipse som er niveaukurven $\mathcal{K
}_{0}(f)$ for andengradspolynomiet $f(x,y) = 2\cdot x^{2} + 2\cdot y^{2} + 2\cdot x\cdot y -8\cdot x -10 
\cdot y + 13$. Se opgave \ref{exercEllipseLevel}  og  eksempel \href{./20-Keglesnit.pdf#evncount.20.1}{
20.1} i eNote \ref{tn20}.}} \label{figEllipseLevel}';
  

你可以修改这个正则表达式(这就是我在现场使用的)

my $reg = qw/((?:[^{}]*(?:{(?:[^{}]*(?:{(?:[^{}]*(?:{[^{}]*})*[^{}]*)*})*[^{}]*)*})*[^{}]*)*)/;

$str=~s/$reg/$1=~s{\#}{\\#}gr; /seg;

print $str;

输出:

 \caption{\small{Et elliptisk omrσde i planen er afgrµnset af en ellipse som er niveaukurven $\mathcal{K  
 }_{0}(f)$ for andengradspolynomiet $f(x,y) = 2\cdot x^{2} + 2\cdot y^{2} + 2\cdot x\cdot y -8\cdot x -10  
 \cdot y + 13$. Se opgave \ref{exercEllipseLevel}  og  eksempel \href{./20-Keglesnit.pdf\#evncount.20.1}{  
 20.1} i eNote \ref{tn20}.}} \label{figEllipseLevel}