[완료]perl, 간단한 정규식 질문드립니다.!

jekai의 이미지

안녕하세요~ 정규식 가끔식 쓰다 오늘 이상하게 보이는게 ( 저만;; )
나와서 질문드립니다.
perl 에서인데요

$_ = "fred xxxxxxxxxxxxxx barney\n" ;
 
s/x*/boom/ ;
 
print $_ ;

이렇게 하면 결과가 boomfred xxxxxxxxxxxxxx barney 라고 나옵니다.
왜이렇죠??

정규식을 s/x+/boom/ 과 같이 사용하면 제대로 매칭이 되어 치환되는데, * 이거는 매칭이 저렇게 되버리네요,

생각해봐도 이유를 알수 없네요, 패턴매칭이 greedy 하게 돌아간다면.. 분명 저기서 + , * 둘다 같게 동작되야 되는데요...

혹시 제가 잘못 생각하고 있나요??

제 잘못된 생각을 바로 잡아주세요 ㅠ_ㅠ

jekai의 이미지

.

hokim의 이미지

* 와 +는 다릅니다. 따라서 위에 결과는 당연한 것입니다.
* => zero or more times
+ => one or more times

jekai의 이미지

* => zero or more times
+ => one or more times

regular expression 의 패턴 매칭은 greedy 하게 동작됩니다.
즉 *를 써도 +를 써도 xxxxxxxxxxxx 는 greedy 하게 매칭이 되야된다는거죠...

zero or more times 면,, more times 로 매칭되야하는게 아닙니까???

hokim의 이미지


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
이와 같은 결과가 나오는것도 제 설명을 뒷받침한다는 생각이 드는군요.

jekai의 이미지

boomfboomrboomeboomdboom boom boombboomaboomrboomnboomeboomyboomboom 이 결과를 보니 알겠네요
그런데 교과서적으로 볼땐 당연히, xxxxxxxxxxx와 매칭되야한다고 생각하는데,,,,

이 경우 공백과 먼저 일치된다니..앞으로 주의해야겠네요...

아 그리고,, 예전부터 궁금했는데 있는데.. sed 를 씨드로 발음하나요 아니면 쎄드로 발음하나요??? ;

feanor의 이미지

스트림 에디터(Stream EDitor)니까 세드로 발음합니다.

aero의 이미지

Perl Regular Expression Mastery
http://perl.plover.com/yak/regex/
요기 있는 자료를 보세요 정규식 내부동작을 아주 잘 설명해줍니다.

jick의 이미지

greedy는 어느 특정 지점에서 greedy하게 동작한다는 뜻이지, 모든 가능한 match를 다 검사해보고 그 중 가장 긴 것을 고른다는 뜻이 아닙니다. 즉 x*가 greedy하다는 얘기는 "지금 현재 x가 세 개 있다 (그러므로 x*를 만족한다), 그런데 뒤에도 x가 또 있다. 여기서 그냥 x 세 개를 리턴할까, 아니면 하나 더 가져갈까?" 이런 상황에서 하나 더 가져오는 방법을 택한다는 뜻이지, 저~~ 멀리 x가 잔뜩 있기 때문에 지금 만들어진 match를 버린다는 뜻이 아닙니다.

이를테면 local하게만 greedy하다고 할 수 있지요.

jekai의 이미지

음.... 내용을 이해 못하겠는데.. 그런데 jick님 말속에 제가 궁금했던게 있는것 같네요, 한번 골똘히 생각해보겠습니다

"여기서 그냥 x 세 개를 리턴할까, 아니면 하나 더 가져갈까?" 랑 " 지금 매치된 패턴을 버릴까? 안버릴까?" 는 같은 의미인것 같은데요 ;;

slomo의 이미지

헤깔리신다면, 다음의 결과를 한번 생각해 보세요. 어떻게 될지는 쉽게 이해하실 겁니다.

$_ = "x fred xx barney xxx\n";
s/x+/boom/;
print $_;

결과는:

boom fred xx barney xxx

greedy하다는 것의 의미가 x보다 xx가 더 길고 xxx가 더 기니까
xxx에 가서 매치가 되어서 "x fred xx barney boom"이 되는
게 아니라는 것은 쉽게 이해가 가실 겁니다.

그러니까 x* 의 경우에

$_ = "fred xx barney xxx\n";
s/x*/boom/;
print $_;

결과는:

boomfred xx barney xxx

그리고 greedy하기 때문에 만약 다음과 같다면:

$_ = "xxxxxx fred xx barney xxx\n";
s/x*/boom/;
print $_;

결과는:

boom fred xx barney xxx

====
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가 하나도 없거나"라는 조건이 성립하기 때문이죠. 이 함정에 빠져든 것입니다.

$_ = "fred xxxxxxxxxxxxxx barney\n" ;
s/x*/boom/ ;
print $_ ;

이 코드의 결과가

boomfred xxxxxxxxxxxxxx barney

인 이유는.. "^" 가 "x*" 와 일치해 버린 것이 가장 큰 이유입니다.

제가 정규식을 대입식으로 공부를 해서 그런지 용어적으로 설명을 하기는 힘들겠지만, 이렇게 예를 들면 좀 더 이해가 빠르리라 생각 됩니다.

P.S
제가 아는 어느분께서 제게 "무한 삽질 대마왕"이라고 부르시더군요. 한편으로는 제게는 슬픈일입니다. 이렇게 밖에 설명을 못해드리는 것이 ^^;

jekai의 이미지

새로 slomo 님 김정균님 말씀들으니 이제 감이 확실히 오는군요 ㅎㅎ 감사합니다.~ ㅎㅎ

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.