[Regular Expression] #7. Regular Expression

김상웅·2022년 6월 11일
0

[Computer Science]

목록 보기
7/10

✅ 들어가면서


사용자는 여러 웹/앱 서비스를 이용하면서 서버에게 자신의 데이터를 넘겨줄 수도, 아닐 수도 있습니다.

티켓을 예약하거나 게시판에 글을 쓰려고 할 때 서버는 사용자의 정보를 알고 싶어할텐데요.

이름 나이 휴대폰번호 이메일 사는곳 성별 주민번호 등 다양한 요소가 정보에 포함될 수 있습니다.

서버는 사용자에 대한 정보, 즉 데이터를 받으면 이것을 어떻게 분류하고 관리할 지 고민을 할 것입니다.

만약 주민등록번호의 뒷자리 7개 숫자를 *로 저장하여 관리하고 싶다면
아래와 같은 코드와 같이 변경을 할 수 있겠습니다:

data = """
	sang 961206-1234567
	woong 960216-2134657
"""

 def condition():
     result = []

	for line in data.split("\n"):
         word_result = []
         for word in line.split(" "):
             if len(word) == 14 and word[:6].isdigit() and word[7:].isdigit():
                 word = word[:6] + "-" + "*******"
             word_result.append(word)
         result.append(" ".join(word_result))

	print("\n".join(result))


condition()

무슨 알고리즘 문제를 풀듯 엄청 긴 코드를 볼 수 있네요.

이것을 정규표현식으로 표현해보겠습니다:

import re

data = """
	sang 961206-1234567
    woong 960216-2134657
"""

pat = re.compile("(\d{6})[-](\d{7})")
print(pat.sub("\g<1>-*******", data))

단 두 줄이면 주민등록번호 뒷자리 7개를 *로 바꿀 수 있습니다..

정규표현식을 사용하는 이유, 사용해야되는 이유 이제 좀 감이 오는 것 같네요!



✅ 정규표현식


문자열의 규칙을 찾아서 조건과 일치하는 것에 대한 처리를 하는 정규표현식에 대해 알아보겠습니다.

그 조건을 작성하는 여러가지 수식이 있습니다.

정규표현식설 명
\d숫자와 매치[0-9]와 동일
\D숫자가 아닌 것과 매치[^0-9]와 동일
\s공백과 매치[ ,\t, \r, \f, \v]과 동일
\S공백이 아닌 것과 매치[^\t, \r, \f, \v]과 동일
\w문자 숫자와 매치[a-zA-Z0-9_]와 동일
\W문자+숫자가 아닌 문자와 매치[^a-zA-Z0-9_]와 동일

📌 문자클래스 []


[] (대괄호) 사이의 문자들과 일치하는지 확인하는 표현식입니다.

[abcdef]

  • ⭕ "a" >> 정규식과 일치하는 "a"가 있습니다.

  • ⭕ "django" >> 정규식과 일치하는 문자인 "a"가 있습니다.

  • ❌ "z" >> 정규식에는 "z"가 없으므로 일치하지 않습니다.

  • ❌ "python" >> 마찬가지로 정규식 문자를 하나도 포함하고 있지 않습니다.

  • - (하이픈)을 사용하여 from-to로 표현할 수 있습니다.
    [a-c] : a, b, c
    [0-5] : 0 1 2 3 4 5


📌 Dot (.)


문자열에서 줄바꿈(\n)을 제외한 모든 문자열이 일치하는지 확인하는 표현식입니다.

a.b

  • ⭕ "aab" >> 가운데 문자 "a"가 모든 문자를 의미하는 . 과 일치합니다.

  • ⭕ "a0b" >> 가운데 문자 "0"이 모든 문자를 의미하는 . 과 일치합니다.

  • ❌ "abc" >> 문자 "a"와 문자 "b" 사이에 어떤 문자라도 하나는 들어있어야 하기 때문에 일치하지 않습니다.


📌 반복 (*)


*표시의 바로 앞 문자가 여러번 반복되는지 확인하는 표현식입니다.

do*g

  • ⭕ "dg" >> "o"가 0번 반복됩니다. ( 반복 0번도 허용합니다.)

  • ⭕ "dog" >> "o"가 0번 이상 반복되어 매치됩니다. (1번 반복)

  • ⭕ "doooog" >> "o"가 0번 이상 반복되어 매치됩니다. (4번 반복)


📌 반복 (+)


+표시의 바로 앞 문자가 여러번 반복되는지 확인하는 표현식입니다.

do+g

  • ⭕ "dg" >> "o"가 0번 반복됩니다. ( 반복 0번을 허용하지 않습니다.)

  • ⭕ "dog" >> "o"가 0번 이상 반복되어 매치됩니다. (1번 반복)

  • ⭕ "doooog" >> "o"가 0번 이상 반복되어 매치됩니다. (4번 반복)

📌 반복 ({m, n}, ?)


+표시의 바로 앞 문자가 m번 이상 n번 이하 반복되는 문자열인지 확인하는 표현식입니다.
? 는 바로 앞 문자가 0회 혹은 1회만 사용되었는지 확인합니다.
? 표현식은 {0, 1}과 같은 표현입니다.

do{2, 5}g

  • ❌ "dg" >> "o"가 0번 반복되어 일치하지 않습니다.

  • ❌ "dog" >> "o"가 1번 반복되어 일치하지 않습니다.

  • ⭕ "doog" >> "o"가 2번 반복되어 매치됩니다.

  • ⭕ "dooooog" >> "o"가 5번 반복되어 매치됩니다.

do?g

  • ⭕ "dog" >> "o"가 1번 반복되어 매치됩니다.

  • ❌ "doog" >> "o"가 2번 반복되어 일치하지 않습니다.



✅ 정규표현식 모듈 사용


파이썬에서는 정규표현식을 지원하는 re 모듈이 있습니다.

다음 코드를 통해 re 모듈을 불러옵니다.

 import re

다음 우리가 사용하려는 정규표현식을 re 모듈의 compile 함수 인자로 넣어줍니다.

그리고 이 정규표현식 객체를 p 또는 pat라는 변수에 담아서 사용합니다. (patter의 p, pat)

p = re.compile("ab*")

이렇게 만든 패턴 객체를 이용하는 방법에는 4가지가 있습니다.

re 모듈을 불러왔다고 가정하고 패턴 객체 이용 방법과 예문만 명시하겠습니다.


📌 Match

아래 패턴 객체는 "a"부터 "z"까지 문자열을 한번 이상 반복하는 문자열인지 확인하는 객체입니다.

match() 함수는 정규표현식과 일치하는 것만 객체로 반환합니다.

p = re.comlpile("[a-z]+")
p.match("python") >> 일치함
p.match("3 python") >> None (일치하지 않음)

위와 같이 표현식에 부합하지 않는 문자열에 대해서는 None 이라는 결과를 반환합니다.


search() 함수는 정규표현식과 일치하는 문자가 문자열에 있다면 객체로 반환합니다.

p = re.comlpile("[a-z]+")
p.search("python") >> 일치함
p.search("3 python") >> 일치함

위와 같이 표현식에 부합하지 않는 문자열에 대해서는 None 이라는 결과를 반환합니다.


📌 Findall

findall() 함수는 정규표현식과 일치하는 문자열에 대해 List의 원소로 반환합니다.

p = re.comlpile("[a-z]+")
p.findall("Python is easy to learn")

결과는 아래와 같습니다:

["Python", "is", "easy", "to", "learn"]

📌 Finditer

findall() 함수는 정규표현식과 일치하는 문자열에 대해 반복 가능한 match object로 반환합니다.

p = re.comlpile("[a-z]+")
objects = p.finditer("Python is easy to learn")

for object in objects :
	print(object)

결과는 아래와 같습니다:

<re.Match object; span=(0, 4), match="Python">
<re.Match object; span=(0, 4), match="is">
<re.Match object; span=(0, 4), match="easy">
<re.Match object; span=(0, 4), match="to">
<re.Match object; span=(0, 4), match="learn">
profile
누구나 이해할 수 있도록

0개의 댓글