2016-02-08 3 views
-2

Мне нужно написать скрипт, который выполняет следующие действия:Perl Regex: нежадным

$ 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 THE back!»

Как исправить эту проблему?

+1

Не уверен, что вы имеете в виду. Является ли выход выше того, что вы получаете, или того, что вы хотите получить? Вы хотите, чтобы 'a' был капитализирован или нет? – jcaron

ответ

1

Итак, вы хотите получить прибыль от pat до th, за исключением случаев 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

Это тоже работало - спасибо за представление – TheyDontHaveIT

0

Итак, вы хотите, чтобы соответствовать каждой последовательности который начинается с pat и заканчивается th, без жадности и в верхнем регистре этой последовательности, вы можете просто использовать выражение в правой части своей замены:

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

И все.

+0

Я был на правильном пути - раньше я делал что-то подобное, но это не сработало (было не известно о «например»). Поэтому я отказался от этого и пошел за дополнительным кодом: (!!!! Спасибо за помощь – TheyDontHaveIT

+0

'e' означает« оценить правую часть как выражение », а не просто строку. Есть еще много полезных флагов, вы можете проверить детали perlop и 'perlre'. – jcaron

Смежные вопросы