2017-08-06 104 views
2

我有* TEX文件包含:列表需要檢查每一個在一個字符串

__DATA__ 
"\left({H^1}, \int {H^2}\right)" 
"\left({H^1},\bigoplus{H^2}\right)" 
"\left({H^1},{H^2}\right)" 
"\left({H^1}, \bigvee {H^2}\right)" 

上面* TEX內容我要檢查我所下面列出的數組元素的列表:如果任何一個元素匹配,然後保留該行:如果沒有一個元素匹配,那麼我需要將\left(替換爲(\right),並將其替換爲)

我的數組:

int frac prod sum oint bigvee bigcup bigcap bigoplus bigotimes 

預期輸出:

"\left({H^1}, \int {H^2}\right)" 
"\left({H^1},\bigoplus{H^2}\right)" 
"({H^1},{H^2})" 
"\left({H^1}, \bigvee {H^2}\right)" 

我曾嘗試:

my @mathenv = qw(int frac prod sum oint bigvee bigcup bigcap bigoplus bigotimes); 

while(<DATA>) { $mathchk .= $_; } 

$boolChk = 'False'; 
$mathchk=~s#\\left\(((?:(?!\\(?:left|right)).)*)\\right\)# my $fulcnt=$&; my $Content=$1; 
foreach my $singlemath(@mathenv) 
{ 
    \#print "S: -$singlemath-\n"; 
    if($fulcnt=~m/\\$singlemath/gi) 
    { $boolChk = 'True'; } 
} 
print ": $boolChk \t$fulcnt\n"; system 'pause'; 
if($boolChk eq 'True') { } 
if($boolChk eq 'False') { $fulcnt = "\($Content\)"; } 
($fulcnt); 
#esg; 

#print $mathchk; 

__DATA__ 
"\left({H^1}, \int {H^2}\right)" 
"\left({H^1},\bigoplus{H^2}\right)" 
"\left({H^1},{H^2}\right)" 
"\left({H^1}, \bigvee {H^2}\right)" 

我能不能夠得到正確的輸出,因此,如果有人指導我在哪裏我必須修改上面的代碼。提前致謝。

回答

2

對於所示的數據

use warnings; 
use strict; 

use List::Util qw(none); 

my @terms = qw(int frac prod sum oint bigvee bigcup bigcap bigoplus bigotimes); 

my ($paren_L, $paren_R) = map { quotemeta $_ } '\left(', '\right)'; 

while (my $line = <DATA>) 
{ 
    if (none { $line =~ /$_/ } @terms) 
    { 
     $line =~ s|$paren_L|(|; 
     $line =~ s|$paren_R|)|; 
    } 
    print $line; 
} 

__DATA__ 
"\left({H^1}, \int {H^2}\right)" 
"\left({H^1},\bigoplus{H^2}\right)" 
"\left({H^1},{H^2}\right)" 
"\left({H^1}, \bigvee {H^2}\right)" 

與輸出

 
"\left({H^1}, \int {H^2}\right)" 
"\left({H^1},\bigoplus{H^2}\right)" 
"({H^1},{H^2})" 
"\left({H^1}, \bigvee {H^2}\right)" 

註記。

  • 這並不說明多重括號表達式在一行

  • 有(許多)其他方式,乳膠指定括號(​​,\Bigg(等)。

另一方面,在Latex文檔中顯示的數據是合理的。

這多次超過線路,但比單個正則表達式更靈活。


有了這樣簡單的模式,我們不必啓動正則表達式引擎每個術語,而是可以構建具有交替一個模式。取代也可被在一個傳完成,使用named capture groups

my $re_terms = '(?:' . join('|', @terms) . ')'; 

while (my $line = <DATA>) 
{ 
    if ($line !~ /$re_terms/) 
    { 
     $line =~ s/(?<L>$paren_L)|(?<R>$paren_R)/$+{L} ? '(' : ')'/eg; 
    } 
    print $line; 
} 

產生相同的輸出。

這確實需要以顯示的格式顯示數據:parens始終配對,一個設置在一行上。

相關問題