초보자 용 질문입니다. 코드에서 :Perl에서 겹쳐지는 패턴 일치
$a = 'aaagggaaa';
(@b) = ($a =~ /(a.+)(g.+)/);
print "$b[0]\n";
왜 aaagg
하지 aaa
동일 $b[0]
입니까? 즉, 두 번째 그룹 인 (g.+)
이 마지막으로 만 일치하는 이유는 g
입니까?
초보자 용 질문입니다. 코드에서 :Perl에서 겹쳐지는 패턴 일치
$a = 'aaagggaaa';
(@b) = ($a =~ /(a.+)(g.+)/);
print "$b[0]\n";
왜 aaagg
하지 aaa
동일 $b[0]
입니까? 즉, 두 번째 그룹 인 (g.+)
이 마지막으로 만 일치하는 이유는 g
입니까?
첫 번째 .+
은 "greedy"이므로 가능하면 많은 문자를 일치 시키려고합니다.
이 "욕심 많은"동작을 끄려면 .+
을 .+?
으로 바꿀 수 있으므로 /(a.+?)(g.+)/
은 ('aaa', 'gggaaa')를 반환합니다.
어쩌면 /(a+)(g+)/
(첫 번째 그룹에만 'a', 두 번째 그룹에는 'g'만 쓸 수 있습니다.
펄 정규 표현식은 일반적으로 가능한 가장 긴 문자열과 일치합니다.
코드에서이 코드는 마지막 g
과 일치하고 aaagg을 반환합니다. aaa으로 결과를 얻으려면 비 탐욕적인 행동을 사용해야합니다.
aaa
분명히, question mark
의 사용이 경기 ungreedy한다 : 출력 그것은 것
$a = 'aaagggaaa';
(@b) = ($a =~ /(a.+?)(g.+)/);
print "$b[0]\n";
:이 코드를 사용합니다.
정규 표현식 당신이 쓴 :
($a =~ /(a.+)(g.+)/);
이 더 많은 문자 다음에 한 "g"
에 을 마무리 "a"
어떤 단어가 할 수있는 한을이나 저전압. 그래서 첫 번째 (a.+)
는 정규 표현식의 두 번째 부분의 경기까지 "aaagg"
일치 : (g.+)
=>"gaaa"
@b
배열이 두 경기를 "aaagg"
및 "gaaa"
를받습니다. 따라서 $b[0]
은 "aaagg"
만을 인쇄합니다.
보통 정규 표현식은 욕심이 있습니다. 당신은 ?
문자를 사용하여 해제 할 수 있습니다
$a = 'aaagggaaa';
my @b = ($a =~ /(a.+)(g.+)/);
my @c = ($a =~ /(a.+?)(g.+)/);
print "@b\n";
print "@c\n";
출력 :
aaagg gaaa
aaa gggaaa
그러나 나는 이것이 당신이 원하는 확실하지 않다! abagggbb
은 어떨까요? aba
이 필요합니까?
첫 번째 .+
은 g
이되도록 오른쪽으로 매치되는 것이 문제입니다.
실제로 무엇이 일어나고 있는지 보여주기 위해 코드를 수정하여 debug 정보를 더 자세히 보여 주도록 수정했습니다.
Compiling REx "a.+[g ]"
Final program:
1: EXACT <a> (3)
3: PLUS (5)
4: REG_ANY (0)
5: ANYOF[ g][] (16)
16: END (0)
anchored "a" at 0 (checking anchored) minlen 3
첫
.+
이 함께 시작하는이 할 수있는 모든 것을 캡처하는 것을
Guessing start of match in sv for REx "a.+[g ]" against "aaagggaaa"
Found anchored substr "a" at offset 0...
Guessed: match at offset 0
Matching REx "a.+[g ]" against "aaagggaaa"
0 <> <aaagggaaa> | 1:EXACT <a>(3)
1 <a> <aagggaaa> | 3:PLUS(5)
REG_ANY can match 8 times out of 2147483647...
9 <aaagggaaa> <> | 5: ANYOF[ g][](16)
failed...
8 <aaagggaa> <a> | 5: ANYOF[ g][](16)
failed...
7 <aaaggga> <aa> | 5: ANYOF[ g][](16)
failed...
6 <aaaggg> <aaa> | 5: ANYOF[ g][](16)
failed...
5 <aaagg> <gaaa> | 5: ANYOF[ g][](16)
6 <aaaggg> <aaa> | 16: END(0)
Match successful!
Freeing REx: "a.+[g ]"
공지 사항
$ perl -Mre=debug -e'q[aaagggaaa] =~ /a.+[g ]/'
.
g
이 일치 할 때까지 역 추적해야합니다. 당신이 원하는 정규식 알고하는 것은 불가능합니다, 당신에서 더 많은 정보가 없으면
/(a+ )(g+ )/x;
/(a.+? )(g.+)/x;
/(a+ )(g.+)/x;
/(a[^g]+)(g.+)/x;
/(a[^g]+)(g+ )/x;
# etc.
: 당신은 아마 원하는 것은
중 하나입니다.
정말 정규 표현식은 그 자체만으로도 Perl의 나머지 부분보다 복잡한 언어입니다.
Perl 정규 표현식 엔진이 실제로 작동하는지 보려면 [Regexp :: Debugger] (https://metacpan.org/pod/Regexp::Debugger) 모듈에서 'rxrx' 유틸리티를 사용해보십시오. 매우 시원하고 교육적입니다. – jreisinger