• 카테고리

    질문 & 답변
  • 세부 분야

    데이터 분석

  • 해결 여부

    미해결

안녕하세요, 정규표현식 관련 질문드립니다.

20.11.09 13:51 작성 조회수 218

1

'^(?!Species$).*' 

위 식이 왜 species를 제외하는 정규표현식인지 이해가 잘 가지 않습니다. 

(?!stringsample)이 'stringsample'를 제외하는 표현인 것과, [^stringsample]이 'stringsample'을 제외하는 표현인 것은 검색으로 알아냈는데 위에 나와있는 표현식과는 또 다른 형태라 혼란스럽습니다. 

왜 (?!Species$) 형태처럼 굳이 제외하는 표현식인 (?! ~~~)괄호 안에 $를 붙여줬는지, 앞과 뒤에 ^와 .*는 왜 오는 것인지(^나 .*가 개별적으로 어떤 의미인지는 알고 있습니다) 헷갈립니다.

다시 설명해주실 수 있나요?

답변 1

답변을 작성해보세요.

2

안녕하세요.

cheat sheet에 있는 예제를 그대로 사용하다 보니 해당 정규표현식을 그대로 가져왔는데요.

정규표현식에 대한 설명이 부족해서 혼란을 드렸네요.

답변에 사용한 코드를 colab 에서 실습해 보실 수 있도록 만들었습니다.

아래 링크와 함께 보세요.

https://colab.research.google.com/github/corazzon/cracking-the-pandas-cheat-sheet/blob/master/06-pandas_cheat_sheet_columns_filter_regex.ipynb

사실 같은 결과를 반환하는 코드지만 아래와 같이 작성해 볼 수도 있습니다.

훨씬 간단한데요. cheat sheet 에서는 아마도 정규표현식의 여러 쓰임을 알려주기 위해 조금 복잡하게 쓴것 같아요.

왜 (?!Species$) 형태처럼 굳이 제외하는 표현식인 (?! ~~~)괄호 안에 $를 붙여줬는지, 앞과 뒤에 ^와 .*는 왜 오는 것인지(^나 .*가 개별적으로 어떤 의미인지는 알고 있습니다) 헷갈립니다.

=> $ 는 제외하더라도 같은 결과를 반환하게 되는데 영상에서 설명하고 있는 것처럼 끝나는 문자를 의미합니다.

cheat sheet 에 있는 내용을 그대로 가져다 사용하다보니 혼란이 있으셨을거 같아요.

제가 보기에도 cheat sheet 에 있는  정규식은 혼란의 여지가 있어 보입니다.

하지만 cheat sheet 에서 이렇게 복잡한 예제를 사용한데는 이유가 있을 것도 같은데요. 정규표현식을 다양하게 사용해 볼 수 있다는 메시지를 주기 위함이지 않을까라고도 생각해 보게 됩니다.

그럼 질문 주신 내용으로 다시 돌아가보면

.* 는 모든 문자를 의미합니다.  그래서 해당 정규표현식을 해석하면 species 라는 단어로 시작하고 끝나는 패턴이지만 뒤에 .*(모든문자) 어떤 문자가 와도 된다는 것을 의미하게 됩니다.  하지만 여기에 있는 예제에서는 .* 를 쓰든 쓰지 않든 차이가 없어서 더 혼란이 있으셨을거 같아요.

아래 species 컬럼을 그대로 복사해서 비교해 보는 예제를 만들어 봤는데요.

위에서 언급한 다음 링크에서 실습해 보실 수 있습니다.

https://colab.research.google.com/github/corazzon/cracking-the-pandas-cheat-sheet/blob/master/06-pandas_cheat_sheet_columns_filter_regex.ipynb

cheat sheet 에 있는 정규표현식을 간소화해서 설명할 필요가 있어 보이네요.

질문 주신 내용은 다음 업데이트 때 반영해 볼 예정입니다.


정규표현식은 규칙이 있는 프로그래밍 언어이기 때문에 한번 익혀두시면 다른 언어를 사용하실 때도 사용해 보실 수 있어요.

여기에서는 일부 내용만을 언급했지만 제대로 익히려면 정규표현식 책이나 위키문서를 읽어보시는 것도 추천합니다.

https://ko.wikipedia.org/wiki/%EC%A0%95%EA%B7%9C_%ED%91%9C%ED%98%84%EC%8B%9D

기능 설명
. 문자 1개의 문자와 일치한다. 단일행 모드에서는 새줄 문자를 제외한다.
[ ] 문자 클래스 "["과 "]" 사이의 문자 중 하나를 선택한다. "¦"를 여러 개 쓴 것과 같은 의미이다. 예를 들면 [abc]d는 ad, bd, cd를 뜻한다. 또한, "-" 기호와 함께 쓰면 범위를 지정할 수 있다. "[a-z]"는 a부터 z까지 중 하나, "[1-9]"는 1부터 9까지 중의 하나를 의미한다.
[^ ] 부정 문자 클래스 안의 문자를 제외한 나머지를 선택한다. 예를 들면 [^abc]d는 ad, bd, cd는 포함하지 않고 ed, fd 등을 포함한다. [^a-z]는 알파벳 소문자로 시작하지 않는 모든 문자를 의미한다.
^ 처음 문자열이나 행의 처음을 의미한다.
$ 문자열이나 행의 끝을 의미한다.
( ) 하위식 여러 식을 하나로 묶을 수 있다. "abc¦adc"와 "a(b¦d)c"는 같은 의미를 가진다.
\n 일치하는 n번째 패턴 일치하는 패턴들 중 n번째를 선택하며, 여기에서 n은 1에서 9 중 하나가 올 수 있다.
* 0회 이상 0개 이상의 문자를 포함한다. "a*b"는 "b", "ab", "aab", "aaab"를 포함한다.
{m, n} m회 이상 n회 이하 "a{1,3}b"는 "ab", "aab", "aaab"를 포함하지만, "b"나 "aaaab"는 포함하지 않는다.

kjr1222님의 프로필

kjr1222

2022.01.07

선생님,

설명 감사드립니다.

 

.* 이 이해가 가지 않아 다시 질문드립니다.

만약

df.filter(regex='^(?!species$).*' )

이 식에서 .*의 유무가 실행 결과에 차이를 주려면 어떠한 열이 추가적으로 들어가면 되는지 예시를 들어주시면 더 잘 이해할 수 있을 것 같습니다.

 

감사합니다.