ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 정규 표현식(Regular Expression)
    Natural Language Processing/딥 러닝을 이용한 자연어 처리 입문 2021. 5. 17. 15:50
    반응형

    https://wikidocs.net/21703 참고하여 공부한 내용 정리함

    05) 정규 표현식(Regular Expression)

    1. 정규 표현식 문법과 모듈 함수


    re모듈을 사용하면 특정 규칙이 있는 텍스트 데이터를 빨흐게 정제할 수 있음

    01) 정규 표현식 문법

    02) 정규 표현식 모듈 함수

    https://wikidocs.net/21703 사이트 참고

    2. 정규 표현식 실습


    1) .기호

    .은 한 개의 임의의 문자를 나타냄

    import re
    r=re.compile("a.c")
    r.search("kkk")

    문자열에 a.c패턴이 존재하지 않아서 결과 출력x

    r.search("abc")
    <re.Match object; span=(0, 3), match='abc'>

    abc 문자열에 a.c 패턴이 있으므로 결과 출력o

    2) ?기호

    ?는 ?앞에 문자가 존재할 수도 있고 안 할 수도 있는 경우를 나타냄

    r=re.compile("ab?c")
    r.search("abbc")

    결과 출력x

    r.search("abc")
    <re.Match object; span=(0, 3), match='abc'>

    b가 존재한다고 판단하여 abc와 매치함

    r.search("ac")
    <re.Match object; span=(0, 2), match='ac'>

    b가 존재하지 않는다고 판단하여 ac와 매치함

    3) *기호

    *은 바로 앞의 문자가 0개 이상일 경우. 앞의 문자는 존재하지 않을 수 있고 여러 개일 수도 있음

    r=re.compile("ab*c")
    r.search("a")

    결과 출력x

    r.search("ac")
    <re.Match object; span=(0, 2), match='ac'>

    b가 존재하지 않는 경우 ac와 매치함

    r.search("abbbbbc")
    <re.Match object; span=(0, 7), match='abbbbbc'>

    b가 여러개 존재하는 경우 abbbbbc와 매치함

    4) +기호

    *와 유사. 다른 점은 앞의 문자가 최소 1개 이상이여야 한다는 점

    r=re.compile("ab+c")
    r.search("ac")

    b가 없기 때문에 매치 x

    r.search("abc")
    <re.Match object; span=(0, 3), match='abc'>

    b가 하나라도 있기에 abc와 매치됨

    r.search("abbbbbc")
    <re.Match object; span=(0, 7), match='abbbbbc'>

    b가 여러개 있으므로 abbbbbc와 매치함

    5) ^기호

    ^는 시작된는 글자를 지정함

    r=re.compile("^a")
    r.search("bbc")

    문자열이 a로 시작되지 않기 때문에 결과 출력 x

    r.search("abc")
    <re.Match object; span=(0, 1), match='a'>

    문자열이 a로 시작되기 때문에 결과 출력 o

    6) {숫자} 기호

    문자에 해당 기호를 붙이면 해당 문자를 숫자만큼 반복한 것을 나타냄

    r=re.compile("ab{2}c")
    r.search("ac")
    r.search("abc")
    r.search("abbbbc")

    결과 x

    r.search("abbc")
    <re.Match object; span=(0, 4), match='abbc'>

    b가 해당 숫자만큼 반복했기에 결과 출력 o

    7) {숫자1,숫자2} 기호

    문자에 해당 기호를 붙이면 해당 문자를 숫자1 이상 숫자2 이하만큼 반복함

    r=re.compile("ab{2,8}c")
    r.search("ac")
    r.search("abc")
    r.search("abbbbbbbbbc")

    b를 2~8 만큼 반복하지 않았기에 결과 출력 x

    r.search("abbc")
    <re.Match object; span=(0, 4), match='abbc'>

    b를 2번 반복했기에 결과 출력 o

    r.search("abbbbbbbbc")
    <re.Match object; span=(0, 10), match='abbbbbbbbc'>

    b를 8번 반복했기에 결과 출력 o

    8) {숫자,} 기호

    문자에 해당 기호를 붙이면 해당 문자를 숫자 이상만큼 반복함

    r=re.compile("ab{2,}c")
    r.search("ac")
    r.search("abc")

    해당 정규 표현식은 b가 2개 이상임. 그래서 결과 출력 x

    r.search("abbbbbbbc")
    <re.Match object; span=(0, 9), match='abbbbbbbc'>

    b를 2번 이상 반복함. 결과 출력 o

    9) [ ] 기호

    [ ] 안에 문자들을 넣으면 그 문자들 중 한 개의 문자와 매치하라는 의미를 가짐. [a-zA-Z]는 알파벳 전부를 의미하고 [0-9]는 숫자 전부를 의미함

    r=re.compile("[abc]")
    r.search("zzz")

    결과 출력 x

    display(r.search("a"))
    display(r.search("aaaa"))
    display(r.search("baaccc"))
    <re.Match object; span=(0, 1), match='a'>
    <re.Match object; span=(0, 1), match='a'>
    <re.Match object; span=(0, 1), match='b'>

    10) [^문자] 기호

    ^ 기호 뒤에 붙은 문자들을 제외한 모든 문자를 매치하는 역할

    r=re.compile("[^abc]")
    r.search("a")
    r.search("ab")
    r.search("b")

    문자 a b c가 들어간 문자열에는 매치되지 않음

    r.search("d1")
    <re.Match object; span=(0, 1), match='d'>

    해당 문자가 없기에 매치됨

    r.search("aabbbdccc")
    <re.Match object; span=(5, 6), match='d'>

    3. 정규 표현식 모듈 함수 예제


    (1) re.match() vs re.search()

    search()는 정규 표현식 전체에 대해 문자열이 매치하는지 봄. match()는 문자열의 첫 부분부터 정규 표현식과 매치하는지를 확인함. 문자열 중간에 패턴이 있더라도 문자열의 시작에서 패턴이 일치하지 않으면 차지 않음

    r=re.compile("ab.")
    r.search("kkkabc")

    search()는 패턴이 문자열 중간에 있어도 매치함

    r.match("kkkabc")

    match()는 패턴이 문자열 중간에 있으면 매치 안 함

    r.match("abckkk")

    match()는 문자열 시작부터 패턴과 일치해야 매치함

    (2) re.split()

    split() 함수는 입력된 정규 표현식을 기준으로 문자열을 분리하여 리스트로 리턴함

    text = "사과 딸기 수박 메론 바나나"
    re.split(" ", text)
    ['사과', '딸기', '수박', '메론', '바나나']

    공백을 기준으로 문자열 분리함

    text = "사과+딸기+수박+메론+바나나"
    re.split("\+", text)
    ['사과', '딸기', '수박', '메론', '바나나']

    다른 정규 표현식을 기준으로 텍스트를 분리할 수 있음

    (3) re.findall()

    findall()은 정규표현식과 매치되는 모든 문자열을 리스트로 리턴

    text="이름 : 김철수\
    전화번호 : 010 - 1234 - 1234\
    나이 : 30\
    성별 : 남"""
    re.findall("\d+", text)
    ['010', '1234', '1234', '30']

    전체 텍스트에서 숫자만 찾아내 리스트로 반환함

    re.findall("\d+", '문자열임..')
    []

    그러나 입력 텍스트에 숫자가 없다면 빈 리스트를 리턴함

    (4) re.sub()

    sub() 정규 표현식 패턴과 일치하는 문자열을 찾아 문자열로 대체할 수 있음

    text = "Regular expression : A regular expression, regex or regexp[1] (sometimes called a rational expression)[2][3] is, in theoretical computer science and formal language theory, a sequence of characters that define a search pattern."
    re.sub('[^a-zA-Z]', ' ', text)
    'Regular expression   A regular expression  regex or regexp     sometimes called a rational expression        is  in theoretical computer science and formal language theory  a sequence of characters that define a search pattern '

    알파벳 외의 문자는 공백으로 처리함

    5. 정규 표현식 텍스트 전처리 예제


    text = """100 John    PROF
    101 James   STUD
    102 Mac   STUD"""
    re.split('\s+', text)
    ['100', 'John', 'PROF', '101', 'James', 'STUD', '102', 'Mac', 'STUD']

    '\s+'는 공백을 찾아내는 정규표현식. +는 최소 1개 이상의 패턴을 찾아낸다는 의미. 공백이 최소 1개 이상인 경우의 패턴을 찾아냄

    re.findall('\d+', text)
    ['100', '101', '102']

    '\d+'는 숫자에 대한 정규표현식. +는 최소 1개 이상의 숫자에 해당하는 값을 의미함

    re.findall('[A-Z]', text)
    ['J', 'P', 'R', 'O', 'F', 'J', 'S', 'T', 'U', 'D', 'M', 'S', 'T', 'U', 'D']

    모든 대문자 각각을 가져옴

    re.findall('[A-Z]{4}', text)
    ['PROF', 'STUD', 'STUD']

    대문자가 연속적으로 4번 등장하는 경우를 조건으로 추가했을 때 결과

    re.findall('[A-Z][a-z]+', text)
    ['John', 'James', 'Mac']

    대소문자가 섞여 있는 경우 가져온 결과

    letters_only = re.sub('[^a-zA-Z]', ' ', text)
    letters_only
    '    John    PROF     James   STUD     Mac   STUD'

    영문자가 아닌 문자 전부 공백으로 치환

    6. 정규 표현식을 이용한 토큰화


    RegexpTokenizer는 정규 표현식을 사용해서 단어 토큰화 수행

    import nltk
    from nltk.tokenize import RegexpTokenizer
    tokenize = RegexpTokenizer("[\w]+")
    print(tokenizer.tokenize("Don't be fooled by the dark sounding name, Mr. Jone's Orphanage is as cheery as cheery goes for a pastry shop"))
    ['Don', 't', 'be', 'fooled', 'by', 'the', 'dark', 'sounding', 'name', 'Mr', 'Jone', 's', 'Orphanage', 'is', 'as', 'cheery', 'as', 'cheery', 'goes', 'for', 'a', 'pastry', 'shop']

    문장에서 구두점을 제외하고 단어들만 가지고 토큰화 수행

    tokenizer = RegexpTokenizer("[\s]+", gaps=True)
    print(tokenizer.tokenize("Don't be fooled by the dark sounding name, Mr. Jone's Orphanage is as cheery as cheery goes for a pastry shop"))
    ["Don't", 'be', 'fooled', 'by', 'the', 'dark', 'sounding', 'name,', 'Mr.', "Jone's", 'Orphanage', 'is', 'as', 'cheery', 'as', 'cheery', 'goes', 'for', 'a', 'pastry', 'shop']

    공백을 기준으로 문장을 토큰화. gaps=True는 해당 정규 표현식을 토큰으로 나누기 위한 기준으로 사용한다는 의미. 아포스트로피나 온점을 제외하지 않고 토큰화가 수행됨

    반응형

    댓글

Designed by Tistory.