2017-09-15 47 views
0

我正在读取.tex文件并根据另一个.tex文件保存的模式进行替换。我离开的分隔符是正则表达式perl匹配分隔的乳胶文本

\ket{ 

和正确的分隔符是

} 

正则表达式\\ket\{(.+)\}可以匹配

 
\ket{0} 

但复杂的线条,如

 
$\ket{\bfG \bfP^L_{2ex}}$, and the real space, $\ket{\bfP^L_{2ex}}$ 

它匹配整个te XT

 
\bfG \bfP^L_{2ex}}$, and the real space, $\ket{\bfP^L_{2ex} 

修改正则表达式

\\ket{([^{}]*|[^}])*}{1,2} 

我可以检测所提到的复杂的线路,但在诸如

 
reciprocal lattice, $\ket{\bfG \bfP^L_{2ex}{3}{2}}$, and the real space, $\ket{\bfP^L_{2ex}}$ 

不起作用。我该如何解决这个问题?我必须阅读哪些算法/主题/书籍/教程来解决这样的问题?

+0

第1步:停止使用[regexes](https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags)。 https://en.wikipedia.org/wiki/Context-free_grammar#Examples – n0rd

+0

请参阅[我应该怎么做当有人回答我的问题?](http://stackoverflow.com/help/someone-answers) – zdim

回答

2

我建议达成处理(复杂)问题平衡/嵌套分隔符的工具,而不是试图手工解析它。也许首先看看核心Text::BalancedRegexp::Common。有关它们的使用示例,请参阅this post,这也与您所需要的非常接近。


在这种情况下,您可以通过使用字符串的特定属性来回避问题。

如果这个公式永远在线,即$...$之间,那么这些$的解决问题

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

my $line = q( 
    $\ket{\bfG \bfP^L_{2ex}}$, and the real space, $\ket{\bfP^L_{2ex}}$ 
); 

my @kets = $line =~ m| \$\\ket{ (.+?) }\s*\$ |gx; 

say for @kets; 

这将打印

 
\bfG \bfP^L_{2ex} 
\bfP^L_{2ex} 

这是很容易,因为你需要的文字仅仅是在字面$\ket{与第一个下一个}$之间;没有什么内部问题,所以嵌套分隔符没有问题。

.+?匹配所有字符,最多符合以下模式,这里}$(带有可选空格,\s*,以防万一)。需要转义$\|x修饰符允许用于可读性的空格。