2017-09-15 89 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修飾符允許用於可讀性的空格。