SlideShare una empresa de Scribd logo
1 de 155
Descargar para leer sin conexión
조금 깊이 들여다보는

qr/정규표현식/
  Korean Perl Workshop 2012
         2012. 10. 20.

            박근영
 @gypark gypark@gmail.com
 http://gypark.pe.kr/wiki/Perl
목차
• 흔히 겪는 오류와 실수

• Perl 5.10 이후에 도입된 정규식 문법

• 자잘한 팁들




Korean Perl Workshop 2012    2
이 문서의 내용과 코드는 주로…
• perlretut (regular expression tutorial)
    – 번역: http://gypark.pe.kr/wiki/Perl/정규표현식


• perlre

• 손에 잡히는 정규표현식
    – 벤 포터, 김경수 번역, 인사이트

• 한 권으로 끝내는 정규표현식
    – 잰 고이바에르츠 외, 김지원 번역, 한빛미디어

• WWW

…등에서 발췌

Korean Perl Workshop 2012                       3
흔히 겪는 오류와 실수




  "어째서 일치하지 않을까요?"
  "어째서 여기에 일치해 버릴까요?"



Korean Perl Workshop 2012   4
정규식의 어려움
• 일치해야 될 문자열에 일치하는 정규식을
  만드는 것은 비교적 쉽다




Korean Perl Workshop 2012   5
• 일치해야 될 문자열에 일치하는 정규식을
  만드는 것은 비교적 쉽다

• 일치하지 말아야 할 문자열에 일치하지 않
  는 정규식을 만드는 것이 어렵다




Korean Perl Workshop 2012   6
• 일치해야 될 문자열에 일치하는 정규식을
  만드는 것은 비교적 쉽다

• 일치하지 말아야 할 문자열에 일치하지 않
  는 정규식을 만드는 것이 어렵다
    – 경우의 수가 무한함
    – 테스트하기 힘듦
    – 상황에 따라 적절한 타협이 필요

Korean Perl Workshop 2012   7
문자열의 앞에서부터 일치
• 정규표현식 일치 검사의 첫번째 원칙


 “문자열에서 가능한 한
가장 앞부분에서 일치시킨다”


Korean Perl Workshop 2012   8
• 간단한 예

"cats and dogs" =~ / dog | cat | bird /x;




                              * 코드 출처:
Korean Perl Workshop 2012       perlretut
                                            9
• 간단한 예

"cats and dogs" =~ / dog | cat | bird /x;


• 후보들의 순서에 무관하게, 앞에서부터 일치




Korean Perl Workshop 2012                   10
• 수량자와 같이 사용할 때

'"10" cats and "20" dogs'




Korean Perl Workshop 2012   11
• 수량자와 같이 사용할 때

'"10" cats and "20" dogs' =~ m/".+"/;

        Greedy quantifier




Korean Perl Workshop 2012               12
• 수량자와 같이 사용할 때

'"10" cats and "20" dogs' =~ m/".+?"/;

        Non-greedy quantifier로 교체




Korean Perl Workshop 2012                13
• 수량자와 같이 사용할 때

'"10" cats and "20" dogs' =~ m/".+?"/;

        성공!




Korean Perl Workshop 2012                14
• 수량자와 같이 사용할 때

'"10" cats and "20" dogs' =~ m/".+?" dogs/;

        뒤에 조건이 추가




Korean Perl Workshop 2012                     15
• 수량자와 같이 사용할 때

'"10" cats and "20" dogs' =~ m/".+?" dogs/;
                            우리가 원한 것

        이것을 기대하지만…




Korean Perl Workshop 2012                     16
• 수량자와 같이 사용할 때

'"10" cats and "20" dogs' =~ m/".+?" dogs/;
실제로 일치하는 부분
                            우리가 원한 것




                 ???
Korean Perl Workshop 2012                     17
• 수량자와 같이 사용할 때

'"10" cats and "20" dogs' =~ m/".+?" dogs/;
실제로 일치하는 부분


        Non-greedy 수량자는 정규식이 일치할 때까지
        문자열을 소모하며 일치부를 확장지킨다.




Korean Perl Workshop 2012                     18
• 수량자와 같이 사용할 때

'"10" cats and "20" dogs' =~ m/"[^"]+" dogs/;

        /./ 대신에 따옴표를 제외한 문자들만 일치하도록 수정




Korean Perl Workshop 2012                       19
• 수량자와 같이 사용할 때

'"10" cats and "20" dogs' =~ m/"[^"]+" dogs/;

        성공




Korean Perl Workshop 2012                       20
• 경계가 한 글자가 아니면……

        "<b>10</b> cats and <b>20</b> dogs"




Korean Perl Workshop 2012                     21
• 경계가 한 글자가 아니면……

        "<b>10</b> cats and <b>20</b> dogs"
                    =~
          m'<b>((?!</b>).)+</b> dogs';

                 부정 전방탐색
                 Negative Lookahead




Korean Perl Workshop 2012                     22
같은 위치에서는 왼쪽 후보부터

"Her name is Janet." =~ / Jane | Janet /x;

   이 문자열은…




                              * 코드 출처:
Korean Perl Workshop 2012       perlretut
                                             23
"Her name is Janet." =~ / Jane | Janet /x;

   이 문자열은…
   절대로 'Janet'에 일치하지 않을 것임




Korean Perl Workshop 2012                    24
"Her name is Janet." =~
                            / Janet | Jane /x
                            / bJaneb | bJanetb /x
                            / bJanet?b /x

   정규식 리터럴에서는 이런 실수가 적지만,
   패턴이 변수에 들어가 있으면 눈에 띄지 않음



Korean Perl Workshop 2012                               25
실패하면 거기서 끝나지 않는다
• 일치에 실패하면, 문자열의 다음 글자부터
  다시 일치를 시도함




Korean Perl Workshop 2012   26
# "ATC GTT GAA TGC AAA TGA CAT GAC"
$dna = "ATCGTTGAATGCAAATGACATGAC";

   "TGA" codon의 위치를 검색




                              * 코드 출처:
Korean Perl Workshop 2012       perlretut
                                            27
# "ATC GTT GAA TGC AAA TGA CAT GAC"
$dna = "ATCGTTGAATGCAAATGACATGAC";
while ( $dna =~ /TGA/g ) {
    print "TGA at ", pos $dna, "n";
}

   1차 시도




Korean Perl Workshop 2012              28
# "ATC GTT GAA TGC AAA TGA CAT GAC"
$dna = "ATCGTTGAATGCAAATGACATGAC";
while ( $dna =~ /TGA/g ) {
    print "TGA at ", pos $dna, "n";
}

TGA at 8
TGA at 18
TGA at 23




Korean Perl Workshop 2012              29
# "ATC GTT GAA TGC AAA TGA CAT GAC"
$dna = "ATCGTTGAATGCAAATGACATGAC";
while ( $dna =~ /(www)*?TGA/g ) {
    print "TGA at ", pos $dna, "n";
}

   2차 시도
   세 글자씩 끊어가며 검색




Korean Perl Workshop 2012              30
# "ATC GTT GAA TGC AAA TGA CAT GAC"
$dna = "ATCGTTGAATGCAAATGACATGAC";
while ( $dna =~ /(www)*?TGA/g ) {
    print "TGA at ", pos $dna, "n";
}

TGA at 18
TGA at 23     ???


… 어째서?

Korean Perl Workshop 2012              31
# "ATC GTT GAA TGC AAA TGA CAT GAC"
$dna = "ATCGTTGAATGCAAATGACATGAC";
while ( $dna =~ /(www)*?TGA/g ) {
    print "TGA at ", pos $dna, "n";
}

TGA at 18                   마지막으로 성공한 후




Korean Perl Workshop 2012                 32
# "ATC GTT GAA TGC AAA TGA CAT GAC"
$dna = "ATCGTTGAATGCAAATGACATGAC";
while ( $dna =~ /(www)*?TGA/g ) {
    print "TGA at ", pos $dna, "n";
}

TGA at 18                   마지막으로 성공한 후
                            그 직후부터 일치를 시도하여 실패하고




Korean Perl Workshop 2012                          33
# "ATC GTT GAA TGC AAA TGA CAT GAC"
$dna = "ATCGTTGAATGCAAATGACATGAC";
while ( $dna =~ /(www)*?TGA/g ) {
    print "TGA at ", pos $dna, "n";
}

TGA at 18                   마지막으로 성공한 후
                            그 직후부터 일치를 시도하여 실패하고
                            그 다음 글자부터 재시도하여 실패하고




Korean Perl Workshop 2012                          34
# "ATC GTT GAA TGC AAA TGA CAT GAC"
$dna = "ATCGTTGAATGCAAATGACATGAC";
while ( $dna =~ /(www)*?TGA/g ) {
    print "TGA at ", pos $dna, "n";
}

TGA at 18                   마지막으로 성공한 후
                            그 직후부터 일치를 시도하여 실패하고
                            그 다음 글자부터 재시도하여 실패하고
TGA at 23                   그 다음 글자부터 재시도하여 성공


Korean Perl Workshop 2012                          35
# "ATC GTT GAA TGC AAA TGA CAT GAC"
$dna = "ATCGTTGAATGCAAATGACATGAC";
while ( $dna =~ /G(www)*?TGA/g ) {
    print "TGA at ", pos $dna, "n";
}

   3차 시도
   /G/ - /g flag를 사용하여 일치된 마지막 지점




Korean Perl Workshop 2012                36
# "ATC GTT GAA TGC AAA TGA CAT GAC"
$dna = "ATCGTTGAATGCAAATGACATGAC";
while ( $dna =~ /G(www)*?TGA/g ) {
    print "TGA at ", pos $dna, "n";
}

TGA at 18        성공
                 앵커에 일치해야 하기 때문에,
                 그 다음 글자부터 진행할 수 없다




Korean Perl Workshop 2012                37
Korean Perl Workshop 2012   38
“…하지 않은 것”을 찾기
• 완전한 단어 “cat”에 일치

   /bcatb/




Korean Perl Workshop 2012   39
• 완전한 단어 “cat”에 일치

   /bcatb/

• 어딘가에 포함되어 있는 “cat”?




Korean Perl Workshop 2012   40
• 완전한 단어 “cat”에 일치

   /bcatb/

• 어딘가에 포함되어 있는 “cat”?
• “cat”을 제외한 모든 단어?




Korean Perl Workshop 2012   41
• 완전한 단어 “cat”에 일치

   /bcatb/

• 어딘가에 포함되어 있는 “cat”?
• “cat”을 제외한 모든 단어?
• “cat”이 포함되지 않은 단어?




Korean Perl Workshop 2012   42
• 어딘가에 포함되어 있는 “cat”

   bobcat, category, staccato, 123cat456 …




                              * 코드 출처:
Korean Perl Workshop 2012     한 권으로 끝내는 정규표현식, 67
                                                    43
• 어딘가에 포함되어 있는 “cat”

   bobcat, category, staccato, 123cat456 …


• 오답
   /BcatB/




Korean Perl Workshop 2012                    44
• 어딘가에 포함되어 있는 “cat”

   bobcat, category, staccato, 123cat456 …


• 오답
   /BcatB/
• 정답
   /Bcat|catB/


Korean Perl Workshop 2012                    45
• “cat”을 제외한 모든 단어
        snake, bat, dog, bobcat, …




                               * 코드 출처:
Korean Perl Workshop 2012      한 권으로 끝내는 정규표현식, 372
                                                      46
• “cat”을 제외한 모든 단어
        snake, bat, dog, bobcat, …


• 흔히 보이는 오답
   /b[^cat]+b/
    – [^…]를 단어를 배제하는 용도로 쓰면 안 됨




Korean Perl Workshop 2012            47
• “cat”을 제외한 모든 단어
        snake, bat, dog, bobcat, …


• 흔히 보이는 오답
   /b[^cat]+b/
    – [^…]를 단어를 배제하는 용도로 쓰면 안 됨
• 마찬가지
  /b[^c][^a][^t]b/



Korean Perl Workshop 2012            48
• “cat”을 제외한 모든 단어
        snake, bat, dog, bobcat, …


• 정답
  /b(?!catb)w+/




Korean Perl Workshop 2012            49
• “cat”이 포함되어 있지 않은 모든 단어
        snake, bat, dog, bobcat, …


        /b(?:(?!cat)w)+b/




                               * 코드 출처:
Korean Perl Workshop 2012      한 권으로 끝내는 정규표현식
                                                 50
“일치하지 않음” vs “아닌 것에 일치함”
$str = 'I paid $30 for 100 apples';




                              * 코드 출처:
Korean Perl Workshop 2012     손에 잡히는 정규표현식, 93
                                                 51
$str = 'I paid $30 for 100 apples';

# 가격에만 일치
$str =~ /$d+/;




Korean Perl Workshop 2012             52
$str = 'I paid $30 for 100 apples';

# '$'는 제외하고 숫자에만 일치
$str =~ /(?<=$)d+/; # 후방탐색




Korean Perl Workshop 2012             53
my $str = 'I paid $30 for 100 apples';

# 가격이 아닌 수량에만 일치??
$str =~ /(?<!$)d+/; # 부정형 후방탐색




Korean Perl Workshop 2012                54
my $str = 'I paid $30 for 100 apples';

# 가격이 아닌 수량에만 일치??
$str =~ /(?<!$)d+/; # 부정형 후방탐색
                      # 실패




Korean Perl Workshop 2012                55
my $str = 'I paid $30 for 100 apples';

# 가격이 아닌 수량에만 일치??
$str =~ /(?<!$)d+/; # 부정형 후방탐색
                      # 실패

$str =~ /b(?<!$)d+/;     # 앵커가 필요함




Korean Perl Workshop 2012                56
전후방탐색의 활용

                    (?<=before)match(?=after)


                 이 형태만 생각하기 쉬움




Korean Perl Workshop 2012                       57
일련의 숫자, 그 뒤에 일련의 문자 형태

# 1a, 1ab, 123abcd, ....
/^d+[a-z]+$/




Korean Perl Workshop 2012   58
• 전체 문자열이 4~6 글자인 것만

    /^d{1}(?:[a-z]){3,5}$/
|   /^d{2}(?:[a-z]){2,4}$/
|   /^d{3}(?:[a-z]){1,3}$/
|   /^d{4}(?:[a-z]){1,2}$/
|   /^d{5}(?:[a-z]){1}$/

                 … 무리입니다


Korean Perl Workshop 2012     59
• 정규식 안의 Perl 코드
/^(d++)
(??{
       my $d = length($1); #    숫자열의 길이에 따라
       my $min = 4-$d;      #   문자열의 최소 최대 길이를
       $min = 1 if $min < 1;#   결정하고
       my $max = 6-$d;
       "[a-z]{$min,$max}"; #    정규식을 구성
   })
$/x;
                 … 무리입니다
Korean Perl Workshop 2012                    60
• 정규식과 코드의 협동

    /^d+[a-z]+$/
and length($_) >= 4
and length($_) <= 6




Korean Perl Workshop 2012   61
• 전방탐색

        /^(?=.{4,6}$)d+[a-z]+$/

        둘 이상의 조건을 동시에 검사




Korean Perl Workshop 2012          62
전방탐색과 조건식 결합
올바른 우편번호 찾기

11111            (o)
22222            (o)
33333-           (x)
44444-4444       (o)




                            * 코드 출처:
Korean Perl Workshop 2012   손에 잡히는 정규표현식, 102
                                                63
올바른 우편번호 찾기

11111            (o)
22222            (o)
33333-           (x)
44444-4444       (o)

/d{5}(-d{4})?/
세번째 문자열을 걸러내지 못함


Korean Perl Workshop 2012   64
올바른 우편번호 찾기

11111            (o)
22222            (o)
33333-           (x)
44444-4444       (o)

/d{5}(?(?=-)-d{4})/
전방탐색이 성공하면 그 뒤의 패턴도 검사


Korean Perl Workshop 2012   65
Case shifting
Q L l U u E

    – Perl에서는 큰따옴표 문자열 문법의 일부

    – 정규표현식 문법이 아님




Korean Perl Workshop 2012       66
$str1 = "uhello"; # $str1 = 'Hello'
'Hello' =~ /$str1/; # 일치됨




Korean Perl Workshop 2012              67
$str1 = "uhello"; # $str1 = 'Hello'
'Hello' =~ /$str1/; # 일치됨

$str2 = 'uhello';          # $str2 = 'uhello'
'Hello' =~ /$str2/;         # 런타임 에러

        “Unrecognized escape u …”

• 사용자 입력을 받은 경우도 마찬가지

Korean Perl Workshop 2012                         68
• 쌍따옴표 문자열 내에 적용되는 순서
    – 변수 치환
    – 이스케이프, 논리 캐릭터
    – Case shift

$ perl -e 'print "QP*rln"'
P*rl
           <- (n 있음)



Korean Perl Workshop 2012      69
• 정규표현식에 적용되는 순서
    – 변수 치환
    – Case shift
    – 이스케이프, 논리 캐릭터




Korean Perl Workshop 2012   70
• 묘하다

"n"   =~   qr/n/          #   일치
"n"   =~   qr/Qn/        #   불일치 (qr/n/, 'n'에 일치)
"n"   =~   qr/Un/        #   불일치! (qr/N/, Perl5.8 이하 에러)
"n"   =~   qr/ln/        #   일치!
"n"   =~   qr/Ln/        #   일치!




Korean Perl Workshop 2012                                71
• 심지어

"Qn" =~ qr/Qn/ # 불일치
"Un" =~ qr/Un/ # 불일치
"Ln" =~ qr/Ln/ # 일치




Korean Perl Workshop 2012   72
Korean Perl Workshop 2012   73
/x flag
$str = "abc - 123";

$str =~ /S+ - d+/;

아주 잘 일치함




Korean Perl Workshop 2012   74
$str = "abc - 123";

$str =~ /
             S+            # 단어
             -              # 대시
             d+            # 숫자
           /x;


이것은 일치하지 않는다!


Korean Perl Workshop 2012          75
$str = "abc - 123";

$str =~ /
             S+           # 단어,공백
             -             # 대시,공백
             d+            # 숫자
           /x;


스페이스는 /[ ]/ 또는 / /로 바꿔야 되는 걸 잊지 말자


Korean Perl Workshop 2012             76
Perl 5.10 ~ Perl 5.14 에서
도입된 문법들
N 메타캐릭터
Relative Backreferences g{3} g{-2}
Named Backreferences (?<year>) g<year>
Branch Reset
PREMATCH, MATCH, POSTMATCH
Possessive Quantifier <[^>]++>, 백트래킹하지 않는 부분식
/r flag
Named Subpattern
Recursive Pattern


                Korean Perl Workshop 2012       77
N metacharacter
/./
임의의 캐릭터 하나
    – /s 옵션이 있을 때는 뉴라인"n"에 일치
    – 없을 때는 뉴라인에 일치하지 않음


/N/
/s 옵션에 무관하게 항상 뉴라인을 제외한
임의의 캐릭터 하나




Korean Perl Workshop 2012        78
Relative backreferences
# 오동작
my $a99a = '([a-z])(d)g2g1'; # a11a, g22g, ...
my $line = 'code=e99e';
if ( $line =~ /^(w+)=$a99a$/ ) {
    print "$1 is validn";
}

앞에 괄호가 추가되면서 번호가 안 맞는다




                             * 코드 출처:
Korean Perl Workshop 2012    perlretut
                                               79
# 오동작
my $a99a = '([a-z])(d)g2g1'; # a11a, g22g, ...
my $line = 'code=e99e';
if ( $line =~ /^(w+)=$a99a$/ ) {
    print "$1 is validn";
}

my $a99a = '([a-z])(d)g{-1}g{-2}'
현재 위치 기준.



Korean Perl Workshop 2012                      80
Named backreferences
• 매치되는 그룹에 이름을 붙임

• 앞의 예 다시

my $a99a =
'(?<char>[a-z])(?<digit>d)g{digit}g{char}';




Korean Perl Workshop 2012                        81
• 그룹의 순서가 서로 다른 패턴을 일괄처리
$fmt1 = '(?<y>dddd)-(?<m>dd)-(?<d>dd)';
$fmt2 = '(?<m>dd)/(?<d>dd)/(?<y>dddd)';
$fmt3 = '(?<d>dd).(?<m>dd).(?<y>dddd)';
for my $d ( qw( 2006-10-21 15.01.2007 10/31/2005 ) )
{
    if ( $d =~ m{$fmt1|$fmt2|$fmt3} ){
        print "day=$+{d} month=$+{m} year=$+{y}n";
    }
}
정규식 외부에서는 %+ 해시를 써서 접근
                              * 코드 출처:
Korean Perl Workshop 2012     perlretut
                                                 82
Branch Reset
$time = '2305';
if ( $time =~ /(dd|d):(dd)|(dd)(dd)/ )
{
    print "hour = $1 minute = $2n";    # ??
    print "hour = $3 minute = $4n";    # ??
}


몇 번째 그룹에 캡처가 될 지 모름
defined 검사 필요

                              * 코드 출처:
Korean Perl Workshop 2012     perlretut
                                                  83
$time = '2305 GMT';
if ( $time =~
     /(?|(dd|d):(dd)|(dd)(dd))s+([A-Z]{3})/
   )
{
     print "hour = $1 minute = $2 zone = $3n";
}

(?| 후보1 | 후보2 | 후보3 | … )


Korean Perl Workshop 2012                         84
$time = '2305 GMT';
if ( $time =~
     /(?|(dd|d):(dd)|(dd)(dd))s+([A-Z]{3})/
   )     1         2      1     2         3

{
     print "hour = $1 minute = $2 zone = $3n";
}

각 후보들마다 그룹 번호가 동일하게 시작


Korean Perl Workshop 2012                         85
• 각 후보 패턴마다 그룹의 개수가 다를 경우, 리셋 그룹
  이후 나타나는 그룹은 가장 높은 번호의 다음 번호부터
  할당

• 주의: Perl 5.14 전 버전에는 버그
    • 의도한 대로 캡처되지 않음
    • 캡처 그룹이 가장 많은 후보 패턴을 제일 먼저 적어주거나
    • 빈 그룹 ()을 넣어 모든 후보의 그룹 개수를 동일하게 만들 것




Korean Perl Workshop 2012               86
PREMATCH, MATCH, POSTMATCH
$` $&     $'

• 정규식 연산에 성능 저하를 가져옴

• 코드 내에 한 번이라도 사용되면, 모든 정규식 연산마다
  저 변수들을 세팅하는 과정을 거침




                            * 코드 출처:
Korean Perl Workshop 2012   www.effectiveperlprogramming.com
                                                               87
'My cat is Buster Bean' =~ m/Buster/;
print "I matched $&n";
    # 여기서 매치 변수를 사용해버렸기 때문에

while (<>) {
    next unless /Bean/;
    # 매치할 때마다 매번 오버헤드가 발생
}




Korean Perl Workshop 2012               88
따라서, 저 세 가지 변수는

• 전혀 사용하지 않거나

• 한 번이라도 사용했다면, 그 다음은 마음대로 사용해도
  됨




Korean Perl Workshop 2012     89
대신 다음 변수들을 사용

•   ${^PREMATCH}            $` 역할
•   ${^MATCH}               $&
•   ${^POSTMATCH}           $'
•   /p flag 명시

• /p flag가 있는 연산에서만 오버헤드 발생




Korean Perl Workshop 2012           90
'My cat is Buster Bean' =~ m/sw+sBean/p;
    # /p 옵션 사용
say "I matched ${^MATCH}";

while (<>) {
    next unless /Bean/;     # 오버헤드 없음
}




Korean Perl Workshop 2012                     91
5.10 전 버전        - 캡처 그룹과 매칭 변수로 대체
• /pattern/      + $` 대신 /(.*?)pattern/ + $1
• /pattern/      + $& 대신 /(pattern)/    + $1
• /pattern/      + $' 대신 /pattern(.*)/ + $+

• use English qw(-no_match_vars)

• 로드한 외부 모듈에서 사용해 버리면 역시 소용 없음




Korean Perl Workshop 2012                      92
Possessive quantifier
'abcdZ' =~ /[a-d]+Z/;




Korean Perl Workshop 2012   93
'abcdZ' =~ /[a-d]+Z/;
• [a-d]+는 'abcd'까지 일치




Korean Perl Workshop 2012   94
'abcdZ' =~ /[a-d]+Z/;
• [a-d]+는 'abcd'까지 일치
• Z는 'Z'에 일치




Korean Perl Workshop 2012   95
'abcdZ' =~ /[a-d]+Z/;
• [a-d]+는 'abcd'까지 일치
• Z는 'Z'에 일치
• 끝~




Korean Perl Workshop 2012   96
'abcda' =~ /[a-d]+Z/;       # 일치하지 않는 문자열




Korean Perl Workshop 2012                   97
'abcda' =~ /[a-d]+Z/; # 일치하지 않는 문자열
• [a-d]+ 는 일단 'abcda' 에 일치




Korean Perl Workshop 2012             98
'abcda' =~ /[a-d]+Z/; # 일치하지 않는 문자열
• [a-d]+ 는 일단 'abcda' 에 일치
• Z가 일치될 문자열이 남아 있지 않으므로




Korean Perl Workshop 2012             99
'abcda' =~ /[a-d]+Z/; # 일치하지 않는 문자열
• [a-d]+ 는 일단 'abcda' 에 일치
• Z가 일치될 문자열이 남아 있지 않으므로
    – 'a'를 내어놓고 재시도




Korean Perl Workshop 2012             100
'abcda' =~ /[a-d]+Z/; # 일치하지 않는 문자열
• [a-d]+ 는 일단 'abcda' 에 일치
• Z가 일치될 문자열이 남아 있지 않으므로
    – 'a'를 내어놓고 재시도
    – 'd'를 내어놓고 재시도
    – …




Korean Perl Workshop 2012             101
'abcda' =~ /[a-d]+Z/; # 일치하지 않는 문자열
• [a-d]+ 는 일단 'abcda' 에 일치
• Z가 일치될 문자열이 남아 있지 않으므로
    – 'a'를 내어놓고 재시도
    – 'd'를 내어놓고 재시도
    – …
• 'bcda'를 대상으로 처음부터 다시
    – …




Korean Perl Workshop 2012             102
'abcda' =~ /[a-d]+Z/;




Korean Perl Workshop 2012   103
;;;;;;;
그, 그만…




Korean Perl Workshop 2012   104
• 독점적인 수량자

?+   *+    ++    {2,5}+


• 일치에 성공한 부분은 백트래킹하지 않음




Korean Perl Workshop 2012   105
'abcda' =~ /[a-d]++Z/;




Korean Perl Workshop 2012   106
'abcda' =~ /[a-d]++Z/;
• [a-d]++ 는 'abcda'에 일치




Korean Perl Workshop 2012   107
'abcda' =~ /[a-d]++Z/;
• [a-d]++ 는 'abcda'에 일치
• Z는 일치에 실패




Korean Perl Workshop 2012   108
'abcda' =~ /[a-d]++Z/;
• [a-d]++ 는 'abcda'에 일치
• Z는 일치에 실패
• 백트래킹하지 않고 곧바로 실패 판정




Korean Perl Workshop 2012   109
'abcda' =~ /[a-d]++Z/;
• [a-d]++ 는 'abcda'에 일치
• Z는 일치에 실패
• 백트래킹하지 않고 곧바로 실패 판정

• 단, 여기서 끝은 아님
    – 문자열의 다음 위치에서 재시도




Korean Perl Workshop 2012   110
Korean Perl Workshop 2012   111
• 주의

'aaaaa' =~ /a++a/;

이것은 일치하지 않는다
• a++가 'aaaaa'에 일치해버리기 때문에 뒤에 a가 일치할 문자열이 남
  지 않음
• 아무 때나 Greedy 수량자 대신 사용할 수는 없음




Korean Perl Workshop 2012               112
• 독점적 수량자를 써도 괜찮은지 판단

'aaaaa' =~ / a++ a /x;      # No
'aaaaa' =~ / a++ b /x;      # Yes




Korean Perl Workshop 2012           113
• 독점적 수량자를 써도 괜찮은지 판단

'aaaaa' =~ / a++ a /x;      # No
'aaaaa' =~ / a++ b /x;      # Yes




• 수량자가 적용되는 부분의 패턴이, 뒤에 오는 패턴과
  일치하지 않으면 괜찮음


Korean Perl Workshop 2012           114
백트래킹을 하지 않는 부분식
• 독점적 수량자의 일반형

/[a-d]++Z/

/(?>[a-d]+)Z/;



• 주의
/(?>[a-d])+Z/;              # 다르다

Korean Perl Workshop 2012           115
/r flag in substitution
$str =~ s/pattern/replacement/
• $str 의 내용을 변경
• 치환 횟수를 반환


$str =~ s/pattern/replacement/r
• $str 을 변경하지 않음
• 복제본을 만들어서 복제본을 변경
• 변경된 복제본 문자열을 반환



Korean Perl Workshop 2012         116
• 기존 코드
my $old = 'hello';
(my $new = $old) =~ s/h/H/; # 괄호 필수!


• 새 코드
my $old = 'hello';
my $new = $old =~ s/h/H/r;




Korean Perl Workshop 2012              117
그게 뭐야

Korean Perl Workshop 2012           118
• 좀 더 유용한 예
my @in =
    qw( Bu1s5ter Mi6mi Roscoe Gin98ger El123la );
# @in의 각 원소에서 숫자를 제거하여
# @out 배열에 저장하고 싶다
my @out = map { my $s = $_; $s =~ s/d+//g; $s } @in;
# 원소를 일일이 복사해야 함




                            * 코드 출처:
Korean Perl Workshop 2012   www.effectiveperlprogramming.com
                                                               119
• 좀 더 유용한 예
my @in =
    qw( Bu1s5ter Mi6mi Roscoe Gin98ger El123la );
# @in의 각 원소에서 숫자를 제거하여
# @out 배열에 저장하고 싶다
my @out = map { my $s = $_; $s =~ s/d+//g; $s } @in;
# 원소를 일일이 복사해야 함

my @out = map { s/d+//gr } @in;


Korean Perl Workshop 2012                        120
Named Subpattern
"수"에 일치되는 정규식의 예 (3, -7, .25, 12.34, -5.67e10 등)
/^
  [+-]? *       # 먼저, 부호와 공백에 매치
  (              # 그 다음 정수 또는 소수의 유효숫자부에 매치
      d+        # a로 시작하면서...
      (
           .d* # a.b 또는 a. 형태의 유효숫자
      )?         # ?는 a 형태의 정수가 오는 경우를 고려한 것
     |.d+      # .b 형태의 유효숫자
  )
  ([eE][+-]?d+)? # 추가적으로 올 수 있는 지수부에 매치
$/x;
                            * 코드 출처:
Korean Perl Workshop 2012   perlretut
                                               121
패턴을 정의하고 이름을 붙인 후 재사용

/^ (?&osg) * ( (?&int)(?&dec)? | (?&dec) )
      (?: [eE](?&osg)(?&int) )? $

     (?(DEFINE)
       (?<osg>[-+]?)        # 생략 가능한 부호
       (?<int>d++)         # 정수
       (?<dec>.(?&int))    # 소수부
     )/x;

Korean Perl Workshop 2012                     122
Recursive Pattern
• 부등호로 둘러싸인 문자열에 일치

        /<.*?>/ 또는 /<[^<>]>/




Korean Perl Workshop 2012      123
• 부등호로 둘러싸인 문자열에 일치

        /<.*?>/ 또는 /<[^<>]>/


• 중첩된 형태에도 일치
"< … < … > … < … < … > > … >"


                 /????/

Korean Perl Workshop 2012       124
• 정규식은 정규문법으로 생성되는 문자열을 표현

• 문맥 무관 문법으로 생성되는 문자열을 표현하는 것에는
  한계가 있음
    – Balanced text
    – Program code


• Text::Balanced
• Regexp::Common
• Parser용 모듈들


Korean Perl Workshop 2012    125
• 재귀 패턴을 사용한 정규식

중첩되지 않는 패턴
<[^<>]++>




Korean Perl Workshop 2012   126
• 재귀 패턴을 사용한 정규식

중첩되지 않는 패턴
<[^<>]++>

중첩된 패턴 =
 < > 안에
         부등호를 제외한 것들
         또는 패턴
     이 반복
Korean Perl Workshop 2012   127
/   <                       >   /x; # 부등호 안에




Korean Perl Workshop 2012                      128
/   <                       >   /x; # 부등호 안에

/   <        [^<>]++        >   /x; # 부등호 외의 것들




Korean Perl Workshop 2012                      129
/   <                         >   /x; # 부등호 안에

/   <        [^<>]++          >   /x; # 부등호 외의 것들

/ (<         [^<>]++ | (?1)   >) /x; # 또는 패턴이




Korean Perl Workshop 2012                        130
/   <                         >   /x; # 부등호 안에

/   <        [^<>]++          >   /x; # 부등호 외의 것들

/ (<         [^<>]++ | (?1)   >) /x; # 또는 패턴이

/ (< (?: [^<>]++ | (?1) )* >) /x; # 반복




Korean Perl Workshop 2012                        131
my $string =<<"HERE";
I have some <brackets in <nested brackets> > and
<another group <nested once <nested twice> > >
and that's it.
HERE

my @groups = $string =~ m/
< (?: [^<>]++ | (?1) )* > )/xg;



                            * 코드 출처:
Korean Perl Workshop 2012   perlfaq6
                                                   132
좋죠?

Korean Perl Workshop 2012         133
그러니

Korean Perl Workshop 2012     134
호스팅 업체 분들,
      Perl 5.14 이상으로 설치 좀 굽신굽신

Korean Perl Workshop 2012        135
자잘한 팁들




Korean Perl Workshop 2012   136
빈 패턴은 항상 일치
/()/
언제나 일치하며, 캡처됨

/(?!)/
언제나 실패하는 패턴




Korean Perl Workshop 2012   137
• 세 단어가 순서 무관하게 가까이 붙어 있는 경우를 검색

        … word1 … word3 … … … word2 …
        (8단어 이내에 세 단어 존재)




                             * 코드 출처:
Korean Perl Workshop 2012    한 권으로 끝내는 정규표현식
                                               138
… word1 … word3 … … … word2 …
/
b
(?:
   (?>word1()|word2()|word3()|(?>1|2|3)w+)bW*?
){3,8}
123
/x




Korean Perl Workshop 2012                         139
… word1 … word3 … … … word2 …
/
b
(?:
   (?>word1()|word2()|word3()|(?>1|2|3)w+)bW*?
){3,8}
123
/x
일단 word1 이 일치하면 ()가 같이 일치하고
1은 그때부터 일치


Korean Perl Workshop 2012                         140
… word1 … word3 … … … word2 …
/
b
(?:
   (?>word1()|word2()|word3()|(?>1|2|3)w+)bW*?
){3,8}
123
/x
일단 word1 이 일치하면 ()가 같이 일치하고
1은 그때부터 일치


Korean Perl Workshop 2012                         141
… word1 … word3 … … … word2 …
/
b
(?:
   (?>word1()|word2()|word3()|(?>1|2|3)w+)bW*?
){3,8}
123
/x
일단 word1 이 일치하면 ()가 같이 일치하고
1은 그때부터 일치


Korean Perl Workshop 2012                         142
… word1 … word3 … … … word2 …
/
b
(?:
   (?>word1()|word2()|word3()|(?>1|2|3)w+)bW*?
){3,8}                     이제부터는 아무 단어나 일치 가능
123
/x
일단 word1 이 일치하면 ()가 같이 일치하고
1은 그때부터 일치


Korean Perl Workshop 2012                         143
… word1 … word3 … … … word2 …
/
b
(?:
   (?>word1()|word2()|word3()|(?>1|2|3)w+)bW*?
){3,8} 최대 8번까지 단어들을 일치시킨 후
123
/x
일단 word1 이 일치하면 ()가 같이 일치하고
1은 그때부터 일치


Korean Perl Workshop 2012                         144
… word1 … word3 … … … word2 …
/
b
(?:
   (?>word1()|word2()|word3()|(?>1|2|3)w+)bW*?
){3,8}
123 전체 패턴이 일치하기 위해서는 여기를 통과해야 함
         즉 word1, word2, word3 이 한번씩 일치되었어야 함
/x
일단 word1 이 일치하면 ()가 같이 일치하고
1은 그때부터 일치


Korean Perl Workshop 2012                         145
Korean Perl Workshop 2012   146
정규식으로만 해결하려 하지 말자
my $str = '1 <b>2</b> 3 4 <b>5 6 7</b> 8';
# 볼드체로 표시되는 숫자들만 추출하고 싶다
# 2, 5, 6, 7

# "5 6 7"을 추출하는 게 아니라서 까다롭다




Korean Perl Workshop 2012                    147
my $str = '1 <b>2</b> 3 4 <b>5 6 7</b> 8';
# 볼드체로 표시되는 숫자들만 추출하고 싶다
# 2, 5, 6, 7

my @numbers =
    ( $str =~ m|d+(?=(?:(?!<b>).)*</b>)|g );




Korean Perl Workshop 2012                       148
my $str = '1 <b>2</b> 3 4 <b>5 6 7</b> 8';
# 볼드체로 표시되는 숫자들만 추출하고 싶다
# 2, 5, 6, 7

while ( $str =~ m|<b>(.*?)</b>|gs ) {
    push @numbers, ($& =~ /d+/g);
}

쉽고,
백트래킹 등을 생각하면 효율도 이게 낫다

Korean Perl Workshop 2012                    149
grep
grep 'd{4}s+' file1 file2

백슬래시 쓰느라 지겨우시죠?




Korean Perl Workshop 2012        150
grep 'd{4}s+' file1 file2

grep -P 'd{4}s+' file1 file2

Perl 정규식을 사용 가능




Korean Perl Workshop 2012        151
vim
/(a|b)+

• vim의 패턴 해석 방식 4가지
   – V : 백슬래시만 특수하게 해석
   – M : set nomagic
   – m : set magic
   – v : "very magic"
      • Perl 정규식과 비슷해짐

/v(a|b)+

Korean Perl Workshop 2012   152
• vim의 Lookaround
   – @= @!     Lookahead
   – @<= @<!   Lookbehind

• 예
/foo(bar)@!
"bar"가 뒤에 오지 않는 "foo"


:help pattern
:help perl-patterns

Korean Perl Workshop 2012     153
Regexp::Debugger
• Damian Conway
• CPAN



use Regexp::Debugger;
 또는
$ rxrx




Korean Perl Workshop 2012   154
"감사합니다" =~
                  /(Q(&A)?)*/


Korean Perl Workshop 2012       155

Más contenido relacionado

Destacado

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by HubspotMarius Sescu
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTExpeed Software
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsPixeldarts
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthThinkNow
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfmarketingartwork
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024Neil Kimberley
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)contently
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024Albert Qian
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsKurio // The Social Media Age(ncy)
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Search Engine Journal
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summarySpeakerHub
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next Tessa Mero
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentLily Ray
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best PracticesVit Horky
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project managementMindGenius
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...RachelPearson36
 

Destacado (20)

2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot2024 State of Marketing Report – by Hubspot
2024 State of Marketing Report – by Hubspot
 
Everything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPTEverything You Need To Know About ChatGPT
Everything You Need To Know About ChatGPT
 
Product Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage EngineeringsProduct Design Trends in 2024 | Teenage Engineerings
Product Design Trends in 2024 | Teenage Engineerings
 
How Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental HealthHow Race, Age and Gender Shape Attitudes Towards Mental Health
How Race, Age and Gender Shape Attitudes Towards Mental Health
 
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdfAI Trends in Creative Operations 2024 by Artwork Flow.pdf
AI Trends in Creative Operations 2024 by Artwork Flow.pdf
 
Skeleton Culture Code
Skeleton Culture CodeSkeleton Culture Code
Skeleton Culture Code
 
PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024PEPSICO Presentation to CAGNY Conference Feb 2024
PEPSICO Presentation to CAGNY Conference Feb 2024
 
Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)Content Methodology: A Best Practices Report (Webinar)
Content Methodology: A Best Practices Report (Webinar)
 
How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024How to Prepare For a Successful Job Search for 2024
How to Prepare For a Successful Job Search for 2024
 
Social Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie InsightsSocial Media Marketing Trends 2024 // The Global Indie Insights
Social Media Marketing Trends 2024 // The Global Indie Insights
 
Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024Trends In Paid Search: Navigating The Digital Landscape In 2024
Trends In Paid Search: Navigating The Digital Landscape In 2024
 
5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary5 Public speaking tips from TED - Visualized summary
5 Public speaking tips from TED - Visualized summary
 
ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd ChatGPT and the Future of Work - Clark Boyd
ChatGPT and the Future of Work - Clark Boyd
 
Getting into the tech field. what next
Getting into the tech field. what next Getting into the tech field. what next
Getting into the tech field. what next
 
Google's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search IntentGoogle's Just Not That Into You: Understanding Core Updates & Search Intent
Google's Just Not That Into You: Understanding Core Updates & Search Intent
 
How to have difficult conversations
How to have difficult conversations How to have difficult conversations
How to have difficult conversations
 
Introduction to Data Science
Introduction to Data ScienceIntroduction to Data Science
Introduction to Data Science
 
Time Management & Productivity - Best Practices
Time Management & Productivity -  Best PracticesTime Management & Productivity -  Best Practices
Time Management & Productivity - Best Practices
 
The six step guide to practical project management
The six step guide to practical project managementThe six step guide to practical project management
The six step guide to practical project management
 
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
Beginners Guide to TikTok for Search - Rachel Pearson - We are Tilt __ Bright...
 

KPW2012 조금 깊이 들여다보는 정규표현식

  • 1. 조금 깊이 들여다보는 qr/정규표현식/ Korean Perl Workshop 2012 2012. 10. 20. 박근영 @gypark gypark@gmail.com http://gypark.pe.kr/wiki/Perl
  • 2. 목차 • 흔히 겪는 오류와 실수 • Perl 5.10 이후에 도입된 정규식 문법 • 자잘한 팁들 Korean Perl Workshop 2012 2
  • 3. 이 문서의 내용과 코드는 주로… • perlretut (regular expression tutorial) – 번역: http://gypark.pe.kr/wiki/Perl/정규표현식 • perlre • 손에 잡히는 정규표현식 – 벤 포터, 김경수 번역, 인사이트 • 한 권으로 끝내는 정규표현식 – 잰 고이바에르츠 외, 김지원 번역, 한빛미디어 • WWW …등에서 발췌 Korean Perl Workshop 2012 3
  • 4. 흔히 겪는 오류와 실수 "어째서 일치하지 않을까요?" "어째서 여기에 일치해 버릴까요?" Korean Perl Workshop 2012 4
  • 5. 정규식의 어려움 • 일치해야 될 문자열에 일치하는 정규식을 만드는 것은 비교적 쉽다 Korean Perl Workshop 2012 5
  • 6. • 일치해야 될 문자열에 일치하는 정규식을 만드는 것은 비교적 쉽다 • 일치하지 말아야 할 문자열에 일치하지 않 는 정규식을 만드는 것이 어렵다 Korean Perl Workshop 2012 6
  • 7. • 일치해야 될 문자열에 일치하는 정규식을 만드는 것은 비교적 쉽다 • 일치하지 말아야 할 문자열에 일치하지 않 는 정규식을 만드는 것이 어렵다 – 경우의 수가 무한함 – 테스트하기 힘듦 – 상황에 따라 적절한 타협이 필요 Korean Perl Workshop 2012 7
  • 8. 문자열의 앞에서부터 일치 • 정규표현식 일치 검사의 첫번째 원칙 “문자열에서 가능한 한 가장 앞부분에서 일치시킨다” Korean Perl Workshop 2012 8
  • 9. • 간단한 예 "cats and dogs" =~ / dog | cat | bird /x; * 코드 출처: Korean Perl Workshop 2012 perlretut 9
  • 10. • 간단한 예 "cats and dogs" =~ / dog | cat | bird /x; • 후보들의 순서에 무관하게, 앞에서부터 일치 Korean Perl Workshop 2012 10
  • 11. • 수량자와 같이 사용할 때 '"10" cats and "20" dogs' Korean Perl Workshop 2012 11
  • 12. • 수량자와 같이 사용할 때 '"10" cats and "20" dogs' =~ m/".+"/; Greedy quantifier Korean Perl Workshop 2012 12
  • 13. • 수량자와 같이 사용할 때 '"10" cats and "20" dogs' =~ m/".+?"/; Non-greedy quantifier로 교체 Korean Perl Workshop 2012 13
  • 14. • 수량자와 같이 사용할 때 '"10" cats and "20" dogs' =~ m/".+?"/; 성공! Korean Perl Workshop 2012 14
  • 15. • 수량자와 같이 사용할 때 '"10" cats and "20" dogs' =~ m/".+?" dogs/; 뒤에 조건이 추가 Korean Perl Workshop 2012 15
  • 16. • 수량자와 같이 사용할 때 '"10" cats and "20" dogs' =~ m/".+?" dogs/; 우리가 원한 것 이것을 기대하지만… Korean Perl Workshop 2012 16
  • 17. • 수량자와 같이 사용할 때 '"10" cats and "20" dogs' =~ m/".+?" dogs/; 실제로 일치하는 부분 우리가 원한 것 ??? Korean Perl Workshop 2012 17
  • 18. • 수량자와 같이 사용할 때 '"10" cats and "20" dogs' =~ m/".+?" dogs/; 실제로 일치하는 부분 Non-greedy 수량자는 정규식이 일치할 때까지 문자열을 소모하며 일치부를 확장지킨다. Korean Perl Workshop 2012 18
  • 19. • 수량자와 같이 사용할 때 '"10" cats and "20" dogs' =~ m/"[^"]+" dogs/; /./ 대신에 따옴표를 제외한 문자들만 일치하도록 수정 Korean Perl Workshop 2012 19
  • 20. • 수량자와 같이 사용할 때 '"10" cats and "20" dogs' =~ m/"[^"]+" dogs/; 성공 Korean Perl Workshop 2012 20
  • 21. • 경계가 한 글자가 아니면…… "<b>10</b> cats and <b>20</b> dogs" Korean Perl Workshop 2012 21
  • 22. • 경계가 한 글자가 아니면…… "<b>10</b> cats and <b>20</b> dogs" =~ m'<b>((?!</b>).)+</b> dogs'; 부정 전방탐색 Negative Lookahead Korean Perl Workshop 2012 22
  • 23. 같은 위치에서는 왼쪽 후보부터 "Her name is Janet." =~ / Jane | Janet /x; 이 문자열은… * 코드 출처: Korean Perl Workshop 2012 perlretut 23
  • 24. "Her name is Janet." =~ / Jane | Janet /x; 이 문자열은… 절대로 'Janet'에 일치하지 않을 것임 Korean Perl Workshop 2012 24
  • 25. "Her name is Janet." =~ / Janet | Jane /x / bJaneb | bJanetb /x / bJanet?b /x 정규식 리터럴에서는 이런 실수가 적지만, 패턴이 변수에 들어가 있으면 눈에 띄지 않음 Korean Perl Workshop 2012 25
  • 26. 실패하면 거기서 끝나지 않는다 • 일치에 실패하면, 문자열의 다음 글자부터 다시 일치를 시도함 Korean Perl Workshop 2012 26
  • 27. # "ATC GTT GAA TGC AAA TGA CAT GAC" $dna = "ATCGTTGAATGCAAATGACATGAC"; "TGA" codon의 위치를 검색 * 코드 출처: Korean Perl Workshop 2012 perlretut 27
  • 28. # "ATC GTT GAA TGC AAA TGA CAT GAC" $dna = "ATCGTTGAATGCAAATGACATGAC"; while ( $dna =~ /TGA/g ) { print "TGA at ", pos $dna, "n"; } 1차 시도 Korean Perl Workshop 2012 28
  • 29. # "ATC GTT GAA TGC AAA TGA CAT GAC" $dna = "ATCGTTGAATGCAAATGACATGAC"; while ( $dna =~ /TGA/g ) { print "TGA at ", pos $dna, "n"; } TGA at 8 TGA at 18 TGA at 23 Korean Perl Workshop 2012 29
  • 30. # "ATC GTT GAA TGC AAA TGA CAT GAC" $dna = "ATCGTTGAATGCAAATGACATGAC"; while ( $dna =~ /(www)*?TGA/g ) { print "TGA at ", pos $dna, "n"; } 2차 시도 세 글자씩 끊어가며 검색 Korean Perl Workshop 2012 30
  • 31. # "ATC GTT GAA TGC AAA TGA CAT GAC" $dna = "ATCGTTGAATGCAAATGACATGAC"; while ( $dna =~ /(www)*?TGA/g ) { print "TGA at ", pos $dna, "n"; } TGA at 18 TGA at 23 ??? … 어째서? Korean Perl Workshop 2012 31
  • 32. # "ATC GTT GAA TGC AAA TGA CAT GAC" $dna = "ATCGTTGAATGCAAATGACATGAC"; while ( $dna =~ /(www)*?TGA/g ) { print "TGA at ", pos $dna, "n"; } TGA at 18 마지막으로 성공한 후 Korean Perl Workshop 2012 32
  • 33. # "ATC GTT GAA TGC AAA TGA CAT GAC" $dna = "ATCGTTGAATGCAAATGACATGAC"; while ( $dna =~ /(www)*?TGA/g ) { print "TGA at ", pos $dna, "n"; } TGA at 18 마지막으로 성공한 후 그 직후부터 일치를 시도하여 실패하고 Korean Perl Workshop 2012 33
  • 34. # "ATC GTT GAA TGC AAA TGA CAT GAC" $dna = "ATCGTTGAATGCAAATGACATGAC"; while ( $dna =~ /(www)*?TGA/g ) { print "TGA at ", pos $dna, "n"; } TGA at 18 마지막으로 성공한 후 그 직후부터 일치를 시도하여 실패하고 그 다음 글자부터 재시도하여 실패하고 Korean Perl Workshop 2012 34
  • 35. # "ATC GTT GAA TGC AAA TGA CAT GAC" $dna = "ATCGTTGAATGCAAATGACATGAC"; while ( $dna =~ /(www)*?TGA/g ) { print "TGA at ", pos $dna, "n"; } TGA at 18 마지막으로 성공한 후 그 직후부터 일치를 시도하여 실패하고 그 다음 글자부터 재시도하여 실패하고 TGA at 23 그 다음 글자부터 재시도하여 성공 Korean Perl Workshop 2012 35
  • 36. # "ATC GTT GAA TGC AAA TGA CAT GAC" $dna = "ATCGTTGAATGCAAATGACATGAC"; while ( $dna =~ /G(www)*?TGA/g ) { print "TGA at ", pos $dna, "n"; } 3차 시도 /G/ - /g flag를 사용하여 일치된 마지막 지점 Korean Perl Workshop 2012 36
  • 37. # "ATC GTT GAA TGC AAA TGA CAT GAC" $dna = "ATCGTTGAATGCAAATGACATGAC"; while ( $dna =~ /G(www)*?TGA/g ) { print "TGA at ", pos $dna, "n"; } TGA at 18 성공 앵커에 일치해야 하기 때문에, 그 다음 글자부터 진행할 수 없다 Korean Perl Workshop 2012 37
  • 39. “…하지 않은 것”을 찾기 • 완전한 단어 “cat”에 일치 /bcatb/ Korean Perl Workshop 2012 39
  • 40. • 완전한 단어 “cat”에 일치 /bcatb/ • 어딘가에 포함되어 있는 “cat”? Korean Perl Workshop 2012 40
  • 41. • 완전한 단어 “cat”에 일치 /bcatb/ • 어딘가에 포함되어 있는 “cat”? • “cat”을 제외한 모든 단어? Korean Perl Workshop 2012 41
  • 42. • 완전한 단어 “cat”에 일치 /bcatb/ • 어딘가에 포함되어 있는 “cat”? • “cat”을 제외한 모든 단어? • “cat”이 포함되지 않은 단어? Korean Perl Workshop 2012 42
  • 43. • 어딘가에 포함되어 있는 “cat” bobcat, category, staccato, 123cat456 … * 코드 출처: Korean Perl Workshop 2012 한 권으로 끝내는 정규표현식, 67 43
  • 44. • 어딘가에 포함되어 있는 “cat” bobcat, category, staccato, 123cat456 … • 오답 /BcatB/ Korean Perl Workshop 2012 44
  • 45. • 어딘가에 포함되어 있는 “cat” bobcat, category, staccato, 123cat456 … • 오답 /BcatB/ • 정답 /Bcat|catB/ Korean Perl Workshop 2012 45
  • 46. • “cat”을 제외한 모든 단어 snake, bat, dog, bobcat, … * 코드 출처: Korean Perl Workshop 2012 한 권으로 끝내는 정규표현식, 372 46
  • 47. • “cat”을 제외한 모든 단어 snake, bat, dog, bobcat, … • 흔히 보이는 오답 /b[^cat]+b/ – [^…]를 단어를 배제하는 용도로 쓰면 안 됨 Korean Perl Workshop 2012 47
  • 48. • “cat”을 제외한 모든 단어 snake, bat, dog, bobcat, … • 흔히 보이는 오답 /b[^cat]+b/ – [^…]를 단어를 배제하는 용도로 쓰면 안 됨 • 마찬가지 /b[^c][^a][^t]b/ Korean Perl Workshop 2012 48
  • 49. • “cat”을 제외한 모든 단어 snake, bat, dog, bobcat, … • 정답 /b(?!catb)w+/ Korean Perl Workshop 2012 49
  • 50. • “cat”이 포함되어 있지 않은 모든 단어 snake, bat, dog, bobcat, … /b(?:(?!cat)w)+b/ * 코드 출처: Korean Perl Workshop 2012 한 권으로 끝내는 정규표현식 50
  • 51. “일치하지 않음” vs “아닌 것에 일치함” $str = 'I paid $30 for 100 apples'; * 코드 출처: Korean Perl Workshop 2012 손에 잡히는 정규표현식, 93 51
  • 52. $str = 'I paid $30 for 100 apples'; # 가격에만 일치 $str =~ /$d+/; Korean Perl Workshop 2012 52
  • 53. $str = 'I paid $30 for 100 apples'; # '$'는 제외하고 숫자에만 일치 $str =~ /(?<=$)d+/; # 후방탐색 Korean Perl Workshop 2012 53
  • 54. my $str = 'I paid $30 for 100 apples'; # 가격이 아닌 수량에만 일치?? $str =~ /(?<!$)d+/; # 부정형 후방탐색 Korean Perl Workshop 2012 54
  • 55. my $str = 'I paid $30 for 100 apples'; # 가격이 아닌 수량에만 일치?? $str =~ /(?<!$)d+/; # 부정형 후방탐색 # 실패 Korean Perl Workshop 2012 55
  • 56. my $str = 'I paid $30 for 100 apples'; # 가격이 아닌 수량에만 일치?? $str =~ /(?<!$)d+/; # 부정형 후방탐색 # 실패 $str =~ /b(?<!$)d+/; # 앵커가 필요함 Korean Perl Workshop 2012 56
  • 57. 전후방탐색의 활용 (?<=before)match(?=after) 이 형태만 생각하기 쉬움 Korean Perl Workshop 2012 57
  • 58. 일련의 숫자, 그 뒤에 일련의 문자 형태 # 1a, 1ab, 123abcd, .... /^d+[a-z]+$/ Korean Perl Workshop 2012 58
  • 59. • 전체 문자열이 4~6 글자인 것만 /^d{1}(?:[a-z]){3,5}$/ | /^d{2}(?:[a-z]){2,4}$/ | /^d{3}(?:[a-z]){1,3}$/ | /^d{4}(?:[a-z]){1,2}$/ | /^d{5}(?:[a-z]){1}$/ … 무리입니다 Korean Perl Workshop 2012 59
  • 60. • 정규식 안의 Perl 코드 /^(d++) (??{ my $d = length($1); # 숫자열의 길이에 따라 my $min = 4-$d; # 문자열의 최소 최대 길이를 $min = 1 if $min < 1;# 결정하고 my $max = 6-$d; "[a-z]{$min,$max}"; # 정규식을 구성 }) $/x; … 무리입니다 Korean Perl Workshop 2012 60
  • 61. • 정규식과 코드의 협동 /^d+[a-z]+$/ and length($_) >= 4 and length($_) <= 6 Korean Perl Workshop 2012 61
  • 62. • 전방탐색 /^(?=.{4,6}$)d+[a-z]+$/ 둘 이상의 조건을 동시에 검사 Korean Perl Workshop 2012 62
  • 63. 전방탐색과 조건식 결합 올바른 우편번호 찾기 11111 (o) 22222 (o) 33333- (x) 44444-4444 (o) * 코드 출처: Korean Perl Workshop 2012 손에 잡히는 정규표현식, 102 63
  • 64. 올바른 우편번호 찾기 11111 (o) 22222 (o) 33333- (x) 44444-4444 (o) /d{5}(-d{4})?/ 세번째 문자열을 걸러내지 못함 Korean Perl Workshop 2012 64
  • 65. 올바른 우편번호 찾기 11111 (o) 22222 (o) 33333- (x) 44444-4444 (o) /d{5}(?(?=-)-d{4})/ 전방탐색이 성공하면 그 뒤의 패턴도 검사 Korean Perl Workshop 2012 65
  • 66. Case shifting Q L l U u E – Perl에서는 큰따옴표 문자열 문법의 일부 – 정규표현식 문법이 아님 Korean Perl Workshop 2012 66
  • 67. $str1 = "uhello"; # $str1 = 'Hello' 'Hello' =~ /$str1/; # 일치됨 Korean Perl Workshop 2012 67
  • 68. $str1 = "uhello"; # $str1 = 'Hello' 'Hello' =~ /$str1/; # 일치됨 $str2 = 'uhello'; # $str2 = 'uhello' 'Hello' =~ /$str2/; # 런타임 에러 “Unrecognized escape u …” • 사용자 입력을 받은 경우도 마찬가지 Korean Perl Workshop 2012 68
  • 69. • 쌍따옴표 문자열 내에 적용되는 순서 – 변수 치환 – 이스케이프, 논리 캐릭터 – Case shift $ perl -e 'print "QP*rln"' P*rl <- (n 있음) Korean Perl Workshop 2012 69
  • 70. • 정규표현식에 적용되는 순서 – 변수 치환 – Case shift – 이스케이프, 논리 캐릭터 Korean Perl Workshop 2012 70
  • 71. • 묘하다 "n" =~ qr/n/ # 일치 "n" =~ qr/Qn/ # 불일치 (qr/n/, 'n'에 일치) "n" =~ qr/Un/ # 불일치! (qr/N/, Perl5.8 이하 에러) "n" =~ qr/ln/ # 일치! "n" =~ qr/Ln/ # 일치! Korean Perl Workshop 2012 71
  • 72. • 심지어 "Qn" =~ qr/Qn/ # 불일치 "Un" =~ qr/Un/ # 불일치 "Ln" =~ qr/Ln/ # 일치 Korean Perl Workshop 2012 72
  • 74. /x flag $str = "abc - 123"; $str =~ /S+ - d+/; 아주 잘 일치함 Korean Perl Workshop 2012 74
  • 75. $str = "abc - 123"; $str =~ / S+ # 단어 - # 대시 d+ # 숫자 /x; 이것은 일치하지 않는다! Korean Perl Workshop 2012 75
  • 76. $str = "abc - 123"; $str =~ / S+ # 단어,공백 - # 대시,공백 d+ # 숫자 /x; 스페이스는 /[ ]/ 또는 / /로 바꿔야 되는 걸 잊지 말자 Korean Perl Workshop 2012 76
  • 77. Perl 5.10 ~ Perl 5.14 에서 도입된 문법들 N 메타캐릭터 Relative Backreferences g{3} g{-2} Named Backreferences (?<year>) g<year> Branch Reset PREMATCH, MATCH, POSTMATCH Possessive Quantifier <[^>]++>, 백트래킹하지 않는 부분식 /r flag Named Subpattern Recursive Pattern Korean Perl Workshop 2012 77
  • 78. N metacharacter /./ 임의의 캐릭터 하나 – /s 옵션이 있을 때는 뉴라인"n"에 일치 – 없을 때는 뉴라인에 일치하지 않음 /N/ /s 옵션에 무관하게 항상 뉴라인을 제외한 임의의 캐릭터 하나 Korean Perl Workshop 2012 78
  • 79. Relative backreferences # 오동작 my $a99a = '([a-z])(d)g2g1'; # a11a, g22g, ... my $line = 'code=e99e'; if ( $line =~ /^(w+)=$a99a$/ ) { print "$1 is validn"; } 앞에 괄호가 추가되면서 번호가 안 맞는다 * 코드 출처: Korean Perl Workshop 2012 perlretut 79
  • 80. # 오동작 my $a99a = '([a-z])(d)g2g1'; # a11a, g22g, ... my $line = 'code=e99e'; if ( $line =~ /^(w+)=$a99a$/ ) { print "$1 is validn"; } my $a99a = '([a-z])(d)g{-1}g{-2}' 현재 위치 기준. Korean Perl Workshop 2012 80
  • 81. Named backreferences • 매치되는 그룹에 이름을 붙임 • 앞의 예 다시 my $a99a = '(?<char>[a-z])(?<digit>d)g{digit}g{char}'; Korean Perl Workshop 2012 81
  • 82. • 그룹의 순서가 서로 다른 패턴을 일괄처리 $fmt1 = '(?<y>dddd)-(?<m>dd)-(?<d>dd)'; $fmt2 = '(?<m>dd)/(?<d>dd)/(?<y>dddd)'; $fmt3 = '(?<d>dd).(?<m>dd).(?<y>dddd)'; for my $d ( qw( 2006-10-21 15.01.2007 10/31/2005 ) ) { if ( $d =~ m{$fmt1|$fmt2|$fmt3} ){ print "day=$+{d} month=$+{m} year=$+{y}n"; } } 정규식 외부에서는 %+ 해시를 써서 접근 * 코드 출처: Korean Perl Workshop 2012 perlretut 82
  • 83. Branch Reset $time = '2305'; if ( $time =~ /(dd|d):(dd)|(dd)(dd)/ ) { print "hour = $1 minute = $2n"; # ?? print "hour = $3 minute = $4n"; # ?? } 몇 번째 그룹에 캡처가 될 지 모름 defined 검사 필요 * 코드 출처: Korean Perl Workshop 2012 perlretut 83
  • 84. $time = '2305 GMT'; if ( $time =~ /(?|(dd|d):(dd)|(dd)(dd))s+([A-Z]{3})/ ) { print "hour = $1 minute = $2 zone = $3n"; } (?| 후보1 | 후보2 | 후보3 | … ) Korean Perl Workshop 2012 84
  • 85. $time = '2305 GMT'; if ( $time =~ /(?|(dd|d):(dd)|(dd)(dd))s+([A-Z]{3})/ ) 1 2 1 2 3 { print "hour = $1 minute = $2 zone = $3n"; } 각 후보들마다 그룹 번호가 동일하게 시작 Korean Perl Workshop 2012 85
  • 86. • 각 후보 패턴마다 그룹의 개수가 다를 경우, 리셋 그룹 이후 나타나는 그룹은 가장 높은 번호의 다음 번호부터 할당 • 주의: Perl 5.14 전 버전에는 버그 • 의도한 대로 캡처되지 않음 • 캡처 그룹이 가장 많은 후보 패턴을 제일 먼저 적어주거나 • 빈 그룹 ()을 넣어 모든 후보의 그룹 개수를 동일하게 만들 것 Korean Perl Workshop 2012 86
  • 87. PREMATCH, MATCH, POSTMATCH $` $& $' • 정규식 연산에 성능 저하를 가져옴 • 코드 내에 한 번이라도 사용되면, 모든 정규식 연산마다 저 변수들을 세팅하는 과정을 거침 * 코드 출처: Korean Perl Workshop 2012 www.effectiveperlprogramming.com 87
  • 88. 'My cat is Buster Bean' =~ m/Buster/; print "I matched $&n"; # 여기서 매치 변수를 사용해버렸기 때문에 while (<>) { next unless /Bean/; # 매치할 때마다 매번 오버헤드가 발생 } Korean Perl Workshop 2012 88
  • 89. 따라서, 저 세 가지 변수는 • 전혀 사용하지 않거나 • 한 번이라도 사용했다면, 그 다음은 마음대로 사용해도 됨 Korean Perl Workshop 2012 89
  • 90. 대신 다음 변수들을 사용 • ${^PREMATCH} $` 역할 • ${^MATCH} $& • ${^POSTMATCH} $' • /p flag 명시 • /p flag가 있는 연산에서만 오버헤드 발생 Korean Perl Workshop 2012 90
  • 91. 'My cat is Buster Bean' =~ m/sw+sBean/p; # /p 옵션 사용 say "I matched ${^MATCH}"; while (<>) { next unless /Bean/; # 오버헤드 없음 } Korean Perl Workshop 2012 91
  • 92. 5.10 전 버전 - 캡처 그룹과 매칭 변수로 대체 • /pattern/ + $` 대신 /(.*?)pattern/ + $1 • /pattern/ + $& 대신 /(pattern)/ + $1 • /pattern/ + $' 대신 /pattern(.*)/ + $+ • use English qw(-no_match_vars) • 로드한 외부 모듈에서 사용해 버리면 역시 소용 없음 Korean Perl Workshop 2012 92
  • 93. Possessive quantifier 'abcdZ' =~ /[a-d]+Z/; Korean Perl Workshop 2012 93
  • 94. 'abcdZ' =~ /[a-d]+Z/; • [a-d]+는 'abcd'까지 일치 Korean Perl Workshop 2012 94
  • 95. 'abcdZ' =~ /[a-d]+Z/; • [a-d]+는 'abcd'까지 일치 • Z는 'Z'에 일치 Korean Perl Workshop 2012 95
  • 96. 'abcdZ' =~ /[a-d]+Z/; • [a-d]+는 'abcd'까지 일치 • Z는 'Z'에 일치 • 끝~ Korean Perl Workshop 2012 96
  • 97. 'abcda' =~ /[a-d]+Z/; # 일치하지 않는 문자열 Korean Perl Workshop 2012 97
  • 98. 'abcda' =~ /[a-d]+Z/; # 일치하지 않는 문자열 • [a-d]+ 는 일단 'abcda' 에 일치 Korean Perl Workshop 2012 98
  • 99. 'abcda' =~ /[a-d]+Z/; # 일치하지 않는 문자열 • [a-d]+ 는 일단 'abcda' 에 일치 • Z가 일치될 문자열이 남아 있지 않으므로 Korean Perl Workshop 2012 99
  • 100. 'abcda' =~ /[a-d]+Z/; # 일치하지 않는 문자열 • [a-d]+ 는 일단 'abcda' 에 일치 • Z가 일치될 문자열이 남아 있지 않으므로 – 'a'를 내어놓고 재시도 Korean Perl Workshop 2012 100
  • 101. 'abcda' =~ /[a-d]+Z/; # 일치하지 않는 문자열 • [a-d]+ 는 일단 'abcda' 에 일치 • Z가 일치될 문자열이 남아 있지 않으므로 – 'a'를 내어놓고 재시도 – 'd'를 내어놓고 재시도 – … Korean Perl Workshop 2012 101
  • 102. 'abcda' =~ /[a-d]+Z/; # 일치하지 않는 문자열 • [a-d]+ 는 일단 'abcda' 에 일치 • Z가 일치될 문자열이 남아 있지 않으므로 – 'a'를 내어놓고 재시도 – 'd'를 내어놓고 재시도 – … • 'bcda'를 대상으로 처음부터 다시 – … Korean Perl Workshop 2012 102
  • 103. 'abcda' =~ /[a-d]+Z/; Korean Perl Workshop 2012 103
  • 105. • 독점적인 수량자 ?+ *+ ++ {2,5}+ • 일치에 성공한 부분은 백트래킹하지 않음 Korean Perl Workshop 2012 105
  • 106. 'abcda' =~ /[a-d]++Z/; Korean Perl Workshop 2012 106
  • 107. 'abcda' =~ /[a-d]++Z/; • [a-d]++ 는 'abcda'에 일치 Korean Perl Workshop 2012 107
  • 108. 'abcda' =~ /[a-d]++Z/; • [a-d]++ 는 'abcda'에 일치 • Z는 일치에 실패 Korean Perl Workshop 2012 108
  • 109. 'abcda' =~ /[a-d]++Z/; • [a-d]++ 는 'abcda'에 일치 • Z는 일치에 실패 • 백트래킹하지 않고 곧바로 실패 판정 Korean Perl Workshop 2012 109
  • 110. 'abcda' =~ /[a-d]++Z/; • [a-d]++ 는 'abcda'에 일치 • Z는 일치에 실패 • 백트래킹하지 않고 곧바로 실패 판정 • 단, 여기서 끝은 아님 – 문자열의 다음 위치에서 재시도 Korean Perl Workshop 2012 110
  • 111. Korean Perl Workshop 2012 111
  • 112. • 주의 'aaaaa' =~ /a++a/; 이것은 일치하지 않는다 • a++가 'aaaaa'에 일치해버리기 때문에 뒤에 a가 일치할 문자열이 남 지 않음 • 아무 때나 Greedy 수량자 대신 사용할 수는 없음 Korean Perl Workshop 2012 112
  • 113. • 독점적 수량자를 써도 괜찮은지 판단 'aaaaa' =~ / a++ a /x; # No 'aaaaa' =~ / a++ b /x; # Yes Korean Perl Workshop 2012 113
  • 114. • 독점적 수량자를 써도 괜찮은지 판단 'aaaaa' =~ / a++ a /x; # No 'aaaaa' =~ / a++ b /x; # Yes • 수량자가 적용되는 부분의 패턴이, 뒤에 오는 패턴과 일치하지 않으면 괜찮음 Korean Perl Workshop 2012 114
  • 115. 백트래킹을 하지 않는 부분식 • 독점적 수량자의 일반형 /[a-d]++Z/ /(?>[a-d]+)Z/; • 주의 /(?>[a-d])+Z/; # 다르다 Korean Perl Workshop 2012 115
  • 116. /r flag in substitution $str =~ s/pattern/replacement/ • $str 의 내용을 변경 • 치환 횟수를 반환 $str =~ s/pattern/replacement/r • $str 을 변경하지 않음 • 복제본을 만들어서 복제본을 변경 • 변경된 복제본 문자열을 반환 Korean Perl Workshop 2012 116
  • 117. • 기존 코드 my $old = 'hello'; (my $new = $old) =~ s/h/H/; # 괄호 필수! • 새 코드 my $old = 'hello'; my $new = $old =~ s/h/H/r; Korean Perl Workshop 2012 117
  • 118. 그게 뭐야 Korean Perl Workshop 2012 118
  • 119. • 좀 더 유용한 예 my @in = qw( Bu1s5ter Mi6mi Roscoe Gin98ger El123la ); # @in의 각 원소에서 숫자를 제거하여 # @out 배열에 저장하고 싶다 my @out = map { my $s = $_; $s =~ s/d+//g; $s } @in; # 원소를 일일이 복사해야 함 * 코드 출처: Korean Perl Workshop 2012 www.effectiveperlprogramming.com 119
  • 120. • 좀 더 유용한 예 my @in = qw( Bu1s5ter Mi6mi Roscoe Gin98ger El123la ); # @in의 각 원소에서 숫자를 제거하여 # @out 배열에 저장하고 싶다 my @out = map { my $s = $_; $s =~ s/d+//g; $s } @in; # 원소를 일일이 복사해야 함 my @out = map { s/d+//gr } @in; Korean Perl Workshop 2012 120
  • 121. Named Subpattern "수"에 일치되는 정규식의 예 (3, -7, .25, 12.34, -5.67e10 등) /^ [+-]? * # 먼저, 부호와 공백에 매치 ( # 그 다음 정수 또는 소수의 유효숫자부에 매치 d+ # a로 시작하면서... ( .d* # a.b 또는 a. 형태의 유효숫자 )? # ?는 a 형태의 정수가 오는 경우를 고려한 것 |.d+ # .b 형태의 유효숫자 ) ([eE][+-]?d+)? # 추가적으로 올 수 있는 지수부에 매치 $/x; * 코드 출처: Korean Perl Workshop 2012 perlretut 121
  • 122. 패턴을 정의하고 이름을 붙인 후 재사용 /^ (?&osg) * ( (?&int)(?&dec)? | (?&dec) ) (?: [eE](?&osg)(?&int) )? $ (?(DEFINE) (?<osg>[-+]?) # 생략 가능한 부호 (?<int>d++) # 정수 (?<dec>.(?&int)) # 소수부 )/x; Korean Perl Workshop 2012 122
  • 123. Recursive Pattern • 부등호로 둘러싸인 문자열에 일치 /<.*?>/ 또는 /<[^<>]>/ Korean Perl Workshop 2012 123
  • 124. • 부등호로 둘러싸인 문자열에 일치 /<.*?>/ 또는 /<[^<>]>/ • 중첩된 형태에도 일치 "< … < … > … < … < … > > … >" /????/ Korean Perl Workshop 2012 124
  • 125. • 정규식은 정규문법으로 생성되는 문자열을 표현 • 문맥 무관 문법으로 생성되는 문자열을 표현하는 것에는 한계가 있음 – Balanced text – Program code • Text::Balanced • Regexp::Common • Parser용 모듈들 Korean Perl Workshop 2012 125
  • 126. • 재귀 패턴을 사용한 정규식 중첩되지 않는 패턴 <[^<>]++> Korean Perl Workshop 2012 126
  • 127. • 재귀 패턴을 사용한 정규식 중첩되지 않는 패턴 <[^<>]++> 중첩된 패턴 = < > 안에 부등호를 제외한 것들 또는 패턴 이 반복 Korean Perl Workshop 2012 127
  • 128. / < > /x; # 부등호 안에 Korean Perl Workshop 2012 128
  • 129. / < > /x; # 부등호 안에 / < [^<>]++ > /x; # 부등호 외의 것들 Korean Perl Workshop 2012 129
  • 130. / < > /x; # 부등호 안에 / < [^<>]++ > /x; # 부등호 외의 것들 / (< [^<>]++ | (?1) >) /x; # 또는 패턴이 Korean Perl Workshop 2012 130
  • 131. / < > /x; # 부등호 안에 / < [^<>]++ > /x; # 부등호 외의 것들 / (< [^<>]++ | (?1) >) /x; # 또는 패턴이 / (< (?: [^<>]++ | (?1) )* >) /x; # 반복 Korean Perl Workshop 2012 131
  • 132. my $string =<<"HERE"; I have some <brackets in <nested brackets> > and <another group <nested once <nested twice> > > and that's it. HERE my @groups = $string =~ m/ < (?: [^<>]++ | (?1) )* > )/xg; * 코드 출처: Korean Perl Workshop 2012 perlfaq6 132
  • 135. 호스팅 업체 분들, Perl 5.14 이상으로 설치 좀 굽신굽신 Korean Perl Workshop 2012 135
  • 136. 자잘한 팁들 Korean Perl Workshop 2012 136
  • 137. 빈 패턴은 항상 일치 /()/ 언제나 일치하며, 캡처됨 /(?!)/ 언제나 실패하는 패턴 Korean Perl Workshop 2012 137
  • 138. • 세 단어가 순서 무관하게 가까이 붙어 있는 경우를 검색 … word1 … word3 … … … word2 … (8단어 이내에 세 단어 존재) * 코드 출처: Korean Perl Workshop 2012 한 권으로 끝내는 정규표현식 138
  • 139. … word1 … word3 … … … word2 … / b (?: (?>word1()|word2()|word3()|(?>1|2|3)w+)bW*? ){3,8} 123 /x Korean Perl Workshop 2012 139
  • 140. … word1 … word3 … … … word2 … / b (?: (?>word1()|word2()|word3()|(?>1|2|3)w+)bW*? ){3,8} 123 /x 일단 word1 이 일치하면 ()가 같이 일치하고 1은 그때부터 일치 Korean Perl Workshop 2012 140
  • 141. … word1 … word3 … … … word2 … / b (?: (?>word1()|word2()|word3()|(?>1|2|3)w+)bW*? ){3,8} 123 /x 일단 word1 이 일치하면 ()가 같이 일치하고 1은 그때부터 일치 Korean Perl Workshop 2012 141
  • 142. … word1 … word3 … … … word2 … / b (?: (?>word1()|word2()|word3()|(?>1|2|3)w+)bW*? ){3,8} 123 /x 일단 word1 이 일치하면 ()가 같이 일치하고 1은 그때부터 일치 Korean Perl Workshop 2012 142
  • 143. … word1 … word3 … … … word2 … / b (?: (?>word1()|word2()|word3()|(?>1|2|3)w+)bW*? ){3,8} 이제부터는 아무 단어나 일치 가능 123 /x 일단 word1 이 일치하면 ()가 같이 일치하고 1은 그때부터 일치 Korean Perl Workshop 2012 143
  • 144. … word1 … word3 … … … word2 … / b (?: (?>word1()|word2()|word3()|(?>1|2|3)w+)bW*? ){3,8} 최대 8번까지 단어들을 일치시킨 후 123 /x 일단 word1 이 일치하면 ()가 같이 일치하고 1은 그때부터 일치 Korean Perl Workshop 2012 144
  • 145. … word1 … word3 … … … word2 … / b (?: (?>word1()|word2()|word3()|(?>1|2|3)w+)bW*? ){3,8} 123 전체 패턴이 일치하기 위해서는 여기를 통과해야 함 즉 word1, word2, word3 이 한번씩 일치되었어야 함 /x 일단 word1 이 일치하면 ()가 같이 일치하고 1은 그때부터 일치 Korean Perl Workshop 2012 145
  • 146. Korean Perl Workshop 2012 146
  • 147. 정규식으로만 해결하려 하지 말자 my $str = '1 <b>2</b> 3 4 <b>5 6 7</b> 8'; # 볼드체로 표시되는 숫자들만 추출하고 싶다 # 2, 5, 6, 7 # "5 6 7"을 추출하는 게 아니라서 까다롭다 Korean Perl Workshop 2012 147
  • 148. my $str = '1 <b>2</b> 3 4 <b>5 6 7</b> 8'; # 볼드체로 표시되는 숫자들만 추출하고 싶다 # 2, 5, 6, 7 my @numbers = ( $str =~ m|d+(?=(?:(?!<b>).)*</b>)|g ); Korean Perl Workshop 2012 148
  • 149. my $str = '1 <b>2</b> 3 4 <b>5 6 7</b> 8'; # 볼드체로 표시되는 숫자들만 추출하고 싶다 # 2, 5, 6, 7 while ( $str =~ m|<b>(.*?)</b>|gs ) { push @numbers, ($& =~ /d+/g); } 쉽고, 백트래킹 등을 생각하면 효율도 이게 낫다 Korean Perl Workshop 2012 149
  • 150. grep grep 'd{4}s+' file1 file2 백슬래시 쓰느라 지겨우시죠? Korean Perl Workshop 2012 150
  • 151. grep 'd{4}s+' file1 file2 grep -P 'd{4}s+' file1 file2 Perl 정규식을 사용 가능 Korean Perl Workshop 2012 151
  • 152. vim /(a|b)+ • vim의 패턴 해석 방식 4가지 – V : 백슬래시만 특수하게 해석 – M : set nomagic – m : set magic – v : "very magic" • Perl 정규식과 비슷해짐 /v(a|b)+ Korean Perl Workshop 2012 152
  • 153. • vim의 Lookaround – @= @! Lookahead – @<= @<! Lookbehind • 예 /foo(bar)@! "bar"가 뒤에 오지 않는 "foo" :help pattern :help perl-patterns Korean Perl Workshop 2012 153
  • 154. Regexp::Debugger • Damian Conway • CPAN use Regexp::Debugger; 또는 $ rxrx Korean Perl Workshop 2012 154
  • 155. "감사합니다" =~ /(Q(&A)?)*/ Korean Perl Workshop 2012 155