2012-09-10 4 views
1

whitespaces 정규식과 일치하는 문자열에서 대체하려고합니다.Perl Regex : 읽기 전용 값 수정 시도했습니다

my $string = "watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid"; 

if ($string =~ m!(Season\s\d+\sEpisode\s\d+)!){ 

    $1 =~ s!\s+!!g; 

    say $1; 

} 

위의 코드를 실행하면 Modification of a read-only value attempted이됩니다. 이제 $1 값을 해당 변수에 대체를 수행하는 것보다 변수에 저장하면 올바르게 작동합니다.

그래서 새 임시 변수를 만들지 않고도 대체를 수행 할 수있는 방법이 있습니까?

추신 : 누군가가 내가 특별한 변수

+0

'Perl 5.14'을 사용하고 있습니다. – RanRag

+0

어떤 결과가 예상됩니까? 나머지 문자열없이 그냥 "Season1Episode1"? –

+0

그냥'say s! \ s + !! g;'할 수 없습니까? – Qnan

답변

6

하지 마십시오 엉망 :) 그냥 당신이 원하는 데이터를 캡처 할 수없는이기 때문에, 한 - 라이너 위의 코드를 작성하는 방법을 나에게 보여줄 수 건설 출력 동안 당신 자신.

$string = "watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid"; 
if ($string =~ m!Season\s(\d+)\sEpisode\s(\d+)!){ 
    say("Season$1Episode$2"); 
} 
+0

니스는 그렇게 생각하지 않았습니다. – RanRag

-1

이 작업을 시도 할 수 있습니다 :

perl -pi -e 'if($_=~/Season\s\d+\sEpisode\s\d/){s/\s+//g;}' file 

는 아래 테스트 : 당신이 원래 문자열

Season1Episode1Season 1 Episode 1을 압축 할 것 같습니다

XXX> cat temp 
watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid 
XXX> perl -pi -e 'if($_=~/Season\s\d+\sEpisode\s\d/){s/\s+//g;}' temp 
XXX> cat temp 
watchdownloadBuffytheVampireSlayerSeason1Episode1GorillavidXXX> 
+0

솔루션이 올바른 경우 downvote가있는 이유는 알 수 있듯이 수정이 인라인으로 수행됩니다. – Vijay

3

이 될 수 있습니다 @- 및 0을 사용하여 편리하게 완료 함께 좌변

이 프로그램으로 substr를 호출 12,아이디어를 보여줍니다

use strict; 
use warnings; 

my $string = "watch download Buffy the Vampire Slayer Season 1 Episode 1 Gorillavid"; 

if ($string =~ /Season\s+\d+\s+Episode\s+\d+/) { 

    substr($string, $-[0], $+[0] - $-[0]) =~ s/\s+//g; 
    print $string; 
} 

당신은 하나이를 작성하려는 이유를 말을하지 않습니다

watch download Buffy the Vampire Slayer Season1Episode1 Gorillavid 

출력 라인,하지만 당신이해야한다면 그러면 당신을 위해 그것을 할 것입니다

perl -pe '/Season\s*\d+\s*Episode\s*\d+/ and substr($_, $-[0], $+[0] - $-[0]) =~ s/\s+//g' myfile 
+0

'@ - 및 @ +'에 대한 관련 문서는 어디에서 찾을 수 있습니까? – RanRag

+1

@RanRag : [여기] (http://perldoc.perl.org/perlvar.html)를보고 '@ LAST_MATCH_START' 및 @LAST_MATCH_END를 검색하십시오. – Borodin

+0

@RanRag'perldoc -v @ -' (적절한 인용문을 사용하십시오. 쉘 보간을 피하십시오.) – TLP

1
$string =~ s{(?<=Season)\s*(\d+)\s*(Episode)\s*(\d+)}{$1$3$2}; 
1

후 스크립트 for 루프를 사용하여 $_의 로컬 인스턴스를 만드는 경우 대체를 인쇄 (쉼표 사용)와 연결하여 사전 인쇄 처리를 수행 할 수 있습니다.

글로벌 /g 옵션을 사용할 때는 괄호가 필요하지 않습니다. 또한 일치하지 않는 항목은 빈 목록을 for 루프에 반환하므로 if 문이 중복되는 것을 유의하십시오.

스크립트에는 다음과 같이 표시됩니다. if 문은 for 루프로 대체됩니다.

for ($string =~ /Season\s+\d+\s+Episode\s+\d+/g) { 
    s/\s+//g; # implies $_ =~ s/\s+//g 
    say;  # implies say $_ 

} 

이것은 주로 하나의 라이너를 보여주기위한 것입니다. 예를 들어 $_ 대신에 어휘 변수를 삽입 할 수 있습니다. 가독성을 높이려면 for my $match (...)을 입력하십시오.