2016-02-08 135 views
-2

我需要編寫一個腳本,執行以下操作:Perl的正則表達式:非貪婪

$ cat testdata.txt 
this is my file containing data 
for checking pattern matching with a patt on the back! 
only one line contains the p word. 

$ ./mygrep5 pat th testdata.txt 
this is my file containing data 
for checking PATTERN MATCHING WITH a PATT ON THe back! 
only one line contains the p word. 

我已經能夠打印與「一」資本以及其修改就行了。我不知道如何只採取需要的。

我一直在搞亂(下面是我的腳本到目前爲止),所有我設法返回的是「PATT ON TH」部分。

#!/usr/bin/perl 

use strict; 
use warnings; 
use feature 'say'; 
use Data::Dump 'pp'; 

my ($f, $s, $t) = @ARGV; 
my @output_lines; 

open(my $fh, '<', $t); 

while (my $line = <$fh>) { 
    if ($line =~ /$f/ && $line =~ /$s/) { 
     $line =~ s/($f.+?$s)/$1/g; 
     my $sub_phrase = uc $1; 
     $line =~ s/$1/$sub_phrase/g; 
     print $line; 
    } 
    #else { 
    #  print $line; 
    #} 
} 

close($fh); 

它返回:「用於檢查模式匹配與PATT ON返回!」

我該如何解決這個問題?

+1

不確定你的意思。輸出是否高於你所得到的或者你想得到的結果?你想讓'a'大寫還是不? – jcaron

回答

1

所以你想從patth大寫,除了包含空格的a實例嗎?最簡單的方法是大寫整個事情,然後修復由空間包圍的任何A實例。

sub capitalize { 
    my $s = shift; 
    my $uc = uc($s); 
    $uc =~ s/ \s \K A (?=\s) /a/xg; 
    return $uc; 
} 

s{ (\Q$f\E .* \Q$s\E) }{ capitalize($1) }xseg; 

的缺點是,將替換任何現有A通過空間與a包圍。以下是更復雜,但不會從問題的困擾:

sub capitalize { 
    my $s = shift; 
    my @parts = $s =~ m{ \G (\s+ | \S+) }xg; 
    for (@parts) { 
     $_ = uc($_) if $_ ne "a"; 
    } 

    return join('', @parts); 
} 

s{ (\Q$f\E .* \Q$s\E) }{ capitalize($1) }xseg; 

的代碼的其餘部分可以簡化爲:

#!/usr/bin/perl 

use strict; 
use warnings; 

sub capitalize { ... } 

my $f = shift; 
my $s = shift; 

while (<>) { 
    s{ (\Q$f\E .* \Q$s\E) }{ capitalize($1) }xseg; 
    print; 
} 
+0

這一個obvs也工作 - 謝謝你的提交 – TheyDontHaveIT

0

所以,你要每個序列匹配以pat開頭並以th結尾,非貪婪且大寫該序列,則可以簡單地使用替換右側的表達式:

$line =~ s/($f.+?$s)/uc($1)/eg; 
$line =~ s/($f.+?$s)/uc($1)/eg; 

就是這樣。

+0

我是在正確的道路上 - 我做了這樣的事情 - 但它不會工作(不知道「eg」)。所以我放棄了它,並去了更多的代碼:(!!!!謝謝你的幫助 – TheyDontHaveIT

+0

'e'的意思是「評估右手部分作爲一個表達式」,而不僅僅是一個字符串。還有更多有用的標誌,你可能想看看'perlop'和'perlre'的細節。 – jcaron