[완료]perl, 간단한 정규식 질문드립니다.!
글쓴이: jekai / 작성시간: 일, 2007/12/23 - 3:13오전
안녕하세요~ 정규식 가끔식 쓰다 오늘 이상하게 보이는게 ( 저만;; )
나와서 질문드립니다.
perl 에서인데요
$_ = "fred xxxxxxxxxxxxxx barney\n" ; s/x*/boom/ ; print $_ ;
이렇게 하면 결과가 boomfred xxxxxxxxxxxxxx barney 라고 나옵니다.
왜이렇죠??
정규식을 s/x+/boom/ 과 같이 사용하면 제대로 매칭이 되어 치환되는데, * 이거는 매칭이 저렇게 되버리네요,
생각해봐도 이유를 알수 없네요, 패턴매칭이 greedy 하게 돌아간다면.. 분명 저기서 + , * 둘다 같게 동작되야 되는데요...
혹시 제가 잘못 생각하고 있나요??
제 잘못된 생각을 바로 잡아주세요 ㅠ_ㅠ
Forums:
방금 sed 로도 해봤는데, 같은 결과가 나오네요...
.
* 와 +는 다릅니다.
* 와 +는 다릅니다. 따라서 위에 결과는 당연한 것입니다.
* => zero or more times
+ => one or more times
다른거는 알지만....
* => zero or more times
+ => one or more times
regular expression 의 패턴 매칭은 greedy 하게 동작됩니다.
즉 *를 써도 +를 써도 xxxxxxxxxxxx 는 greedy 하게 매칭이 되야된다는거죠...
zero or more times 면,, more times 로 매칭되야하는게 아닙니까???
xx* 의 경우의 결과가
xx* 의 경우의 결과가 fred boom barney 인 것을 보면 greedy 하게 작동하는 것은 맞는 것 같습니다만
c*나 c+(여기서 c는 임의의 문자)이전의 문자들의 패턴 매칭이 우선하는 것 같습니다. 위의 예 같은 경우 x* 이므로
x이전의 문자 매칭을 우선시하고(여기서는 어떤 문자도 없는 경우인데 fred xxx... 에서 f앞의 문자없음이 매칭된 것으로
보아야 합니다.) 그다음에야 x*매칭을 다루는 것 같습니다 그래서
boomfred xxxxxxxxxxxxxx barney
boom
이런 결과를 갖는 것이고
sed 's/x*/boom/g'라고 끝에 global 옵션을 주었을때롤 보면
boomfboomrboomeboomdboom boom boombboomaboomrboomnboomeboomyboom
boom
이와 같은 결과가 나오는것도 제 설명을 뒷받침한다는 생각이 드는군요.
네...그렇군요..그렇지만...
boomfboomrboomeboomdboom boom boombboomaboomrboomnboomeboomyboomboom 이 결과를 보니 알겠네요
그런데 교과서적으로 볼땐 당연히, xxxxxxxxxxx와 매칭되야한다고 생각하는데,,,,
이 경우 공백과 먼저 일치된다니..앞으로 주의해야겠네요...
아 그리고,, 예전부터 궁금했는데 있는데.. sed 를 씨드로 발음하나요 아니면 쎄드로 발음하나요??? ;
sed의 발음
스트림 에디터(Stream EDitor)니까 세드로 발음합니다.
Perl Regular Expression Mastery
Perl Regular Expression Mastery
http://perl.plover.com/yak/regex/
요기 있는 자료를 보세요 정규식 내부동작을 아주 잘 설명해줍니다.
greedy라는 건...
greedy는 어느 특정 지점에서 greedy하게 동작한다는 뜻이지, 모든 가능한 match를 다 검사해보고 그 중 가장 긴 것을 고른다는 뜻이 아닙니다. 즉 x*가 greedy하다는 얘기는 "지금 현재 x가 세 개 있다 (그러므로 x*를 만족한다), 그런데 뒤에도 x가 또 있다. 여기서 그냥 x 세 개를 리턴할까, 아니면 하나 더 가져갈까?" 이런 상황에서 하나 더 가져오는 방법을 택한다는 뜻이지, 저~~ 멀리 x가 잔뜩 있기 때문에 지금 만들어진 match를 버린다는 뜻이 아닙니다.
이를테면 local하게만 greedy하다고 할 수 있지요.
음.... 내용을 이해 못하겠는데..
음.... 내용을 이해 못하겠는데.. 그런데 jick님 말속에 제가 궁금했던게 있는것 같네요, 한번 골똘히 생각해보겠습니다
"여기서 그냥 x 세 개를 리턴할까, 아니면 하나 더 가져갈까?" 랑 " 지금 매치된 패턴을 버릴까? 안버릴까?" 는 같은 의미인것 같은데요 ;;
헤깔리신다면,
헤깔리신다면, 다음의 결과를 한번 생각해 보세요. 어떻게 될지는 쉽게 이해하실 겁니다.
결과는:
greedy하다는 것의 의미가 x보다 xx가 더 길고 xxx가 더 기니까
xxx에 가서 매치가 되어서 "x fred xx barney boom"이 되는
게 아니라는 것은 쉽게 이해가 가실 겁니다.
그러니까 x* 의 경우에
결과는:
그리고 greedy하기 때문에 만약 다음과 같다면:
결과는:
====
No one asks you for change or directions.
-- Slo-Mo, J. Krokidas
====
No one asks you for change or directions.
-- Slo-Mo, J. Krokidas
이게 함정이
이게 함정이 있네요.
x* 은 xxxxxxxxxx 랑 매치될 것이라는 것이 함정입니다.
x+ 는 무조건 x로 시작해야 하지만 x* 은 x로 시작하지 않는 것도 일치하기 때문입니다. 즉,
abc 는 x* 과 일치를 한다는 의미이죠. "x가 하나도 없거나"라는 조건이 성립하기 때문이죠. 이 함정에 빠져든 것입니다.
이 코드의 결과가
인 이유는.. "^" 가 "x*" 와 일치해 버린 것이 가장 큰 이유입니다.
제가 정규식을 대입식으로 공부를 해서 그런지 용어적으로 설명을 하기는 힘들겠지만, 이렇게 예를 들면 좀 더 이해가 빠르리라 생각 됩니다.
P.S
제가 아는 어느분께서 제게 "무한 삽질 대마왕"이라고 부르시더군요. 한편으로는 제게는 슬픈일입니다. 이렇게 밖에 설명을 못해드리는 것이 ^^;
답변감사합니다.~ ㅎㅎ
새로 slomo 님 김정균님 말씀들으니 이제 감이 확실히 오는군요 ㅎㅎ 감사합니다.~ ㅎㅎ
댓글 달기