사용자는 여러 웹/앱 서비스를 이용하면서 서버에게 자신의 데이터를 넘겨줄 수도, 아닐 수도 있습니다.
티켓을 예약하거나 게시판에 글을 쓰려고 할 때 서버는 사용자의 정보를 알고 싶어할텐데요.
이름
나이
휴대폰번호
이메일
사는곳
성별
주민번호
등 다양한 요소가 정보에 포함될 수 있습니다.
서버는 사용자에 대한 정보, 즉 데이터를 받으면 이것을 어떻게 분류하고 관리할 지 고민을 할 것입니다.
만약 주민등록번호
의 뒷자리 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
문자열에서 줄바꿈(\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번 이하 반복되는 문자열인지 확인하는 표현식입니다.
?
는 바로 앞 문자가 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 모듈을 불러왔다고 가정하고 패턴 객체 이용 방법과 예문만 명시하겠습니다.
아래 패턴 객체는 "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()
함수는 정규표현식과 일치하는 문자열에 대해 List
의 원소로 반환합니다.
p = re.comlpile("[a-z]+")
p.findall("Python is easy to learn")
결과는 아래와 같습니다:
["Python", "is", "easy", "to", "learn"]
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">