[파이썬] μ •κ·œν‘œν˜„μ‹ ν™œμš© 방법

Posted by Euisuk's Dev Log on September 11, 2024

[파이썬] μ •κ·œν‘œν˜„μ‹ ν™œμš© 방법

원본 κ²Œμ‹œκΈ€: https://velog.io/@euisuk-chung/파이썬-μ •κ·œν‘œν˜„μ‹-ν™œμš©-방법

μ •κ·œν‘œν˜„μ‹(Regular Expression, RegEx)은 λ¬Έμžμ—΄μ„ μ²˜λ¦¬ν•˜κ³  νŒ¨ν„΄μ„ κ²€μƒ‰ν•˜κ±°λ‚˜ λ³€ν˜•ν•  λ•Œ 맀우 μœ μš©ν•œ λ„κ΅¬μž…λ‹ˆλ‹€. 데이터 κ³Όν•™κ³Ό μ›Ή μŠ€ν¬λž˜ν•‘, ν…μŠ€νŠΈ 처리 λ“± λ‹€μ–‘ν•œ μž‘μ—…μ—μ„œ λ¬Έμžμ—΄μ„ λ‹€λ£° λ•Œ μ •κ·œν‘œν˜„μ‹μ€ ν•„μˆ˜μ μœΌλ‘œ μ‚¬μš©λ©λ‹ˆλ‹€.

이번 ν¬μŠ€νŠΈμ—μ„œλŠ” νŒŒμ΄μ¬μ—μ„œ re λͺ¨λ“ˆμ„ μ‚¬μš©ν•΄ μ •κ·œν‘œν˜„μ‹μ„ μ–΄λ–»κ²Œ ν™œμš©ν•  수 μžˆλŠ”μ§€μ— λŒ€ν•΄ μžμ„Ένžˆ μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

  1. μ •κ·œν‘œν˜„μ‹μ΄λž€?

μ •κ·œν‘œν˜„μ‹μ€ νŠΉμ • νŒ¨ν„΄μ„ κ°€μ§„ λ¬Έμžμ—΄μ„ μ°ΎκΈ° μœ„ν•œ 검색 νŒ¨ν„΄μž…λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, 이메일 μ£Όμ†Œλ₯Ό μ°Ύκ±°λ‚˜ μ „ν™”λ²ˆν˜Έμ™€ 같은 νŠΉμ • ν˜•μ‹μ˜ 데이터λ₯Ό μΆ”μΆœν•  λ•Œ μ‚¬μš©λ  수 μžˆμŠ΅λ‹ˆλ‹€.

μ •κ·œν‘œν˜„μ‹μ˜ 기본적인 κ°œλ…μ€ νŒ¨ν„΄μ„ μ •μ˜ν•˜κ³ , κ·Έ νŒ¨ν„΄μ„ 기반으둜 λ¬Έμžμ—΄μ„ κ²€μƒ‰ν•˜κ±°λ‚˜ λ³€ν˜•ν•˜λŠ” κ²ƒμž…λ‹ˆλ‹€. νŒŒμ΄μ¬μ—μ„œλŠ” 이λ₯Ό μœ„ν•΄ re λͺ¨λ“ˆμ„ μ‚¬μš©ν•©λ‹ˆλ‹€.

  1. μ •κ·œν‘œν˜„μ‹μ—μ„œ μ£Όμš” κ°œλ… 및 νŒ¨ν„΄

μ •κ·œν‘œν˜„μ‹(Regular Expression, RegEx)은 λ¬Έμžλ“€λ‘œ 이루어진 νŒ¨ν„΄μ„ μ •μ˜ν•˜κ³ , 이 νŒ¨ν„΄μ„ μ‚¬μš©ν•΄ νŠΉμ • λ¬Έμžμ—΄μ„ μ°Ύκ±°λ‚˜ λ°”κΎΈλŠ” λ„κ΅¬μž…λ‹ˆλ‹€. μ‰½κ²Œ 말해, μ •κ·œν‘œν˜„μ‹μ€ λ¬Έμžμ—΄μ—μ„œ μ›ν•˜λŠ” 뢀뢄을 μžλ™μœΌλ‘œ μ°Ύμ•„λ‚΄λŠ” β€˜λ§€μš° λ˜‘λ˜‘ν•œβ€™ 방법이라고 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

μ•„λž˜μ—μ„œ μ •κ·œν‘œν˜„μ‹μ—μ„œ 자주 μ“°μ΄λŠ” μ£Όμš” κ°œλ…λ“€μ„ ν•˜λ‚˜μ”© μ•Œμ•„λ³΄κ² μŠ΅λ‹ˆλ‹€.

  1. . (점): μž„μ˜μ˜ ν•œ λ¬Έμžμ™€ μΌμΉ˜ν•©λ‹ˆλ‹€.

    • 예: a.cλŠ” β€œabc”, β€œaxc”, β€œa7c”와 μΌμΉ˜ν•˜μ§€λ§Œ β€œac”, β€œabbcβ€μ™€λŠ” μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  2. \d (숫자): 숫자(0~9)와 μΌμΉ˜ν•©λ‹ˆλ‹€.

    • 예: \d\dλŠ” β€œ12”, β€œ89”, β€œ45”와 같은 두 자리 μˆ«μžμ™€ μΌμΉ˜ν•©λ‹ˆλ‹€.
  3. \D (μˆ«μžκ°€ μ•„λ‹˜): μˆ«μžκ°€ μ•„λ‹Œ λ¬Έμžμ™€ μΌμΉ˜ν•©λ‹ˆλ‹€.

    • 예: \DλŠ” β€œa”, β€œZ”, β€œ!”와 μΌμΉ˜ν•˜μ§€λ§Œ β€œ1β€κ³ΌλŠ” μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  4. \w (λ¬Έμžμ™€ 숫자): μ•ŒνŒŒλ²³ 문자, 숫자, 밑쀄(_)κ³Ό μΌμΉ˜ν•©λ‹ˆλ‹€.

    • 예: \w\w\wλŠ” β€œabc”, β€œ123”, β€œA2_β€œμ™€ 같은 μ„Έ 개의 문자 λ˜λŠ” μˆ«μžμ™€ μΌμΉ˜ν•©λ‹ˆλ‹€.
  5. \W (λ¬Έμžμ™€ μˆ«μžκ°€ μ•„λ‹˜): μ•ŒνŒŒλ²³ 문자, 숫자, 밑쀄(_)이 μ•„λ‹Œ λ¬Έμžμ™€ μΌμΉ˜ν•©λ‹ˆλ‹€.

    • 예: \WλŠ” β€œ!”, β€œ@”, β€œ#”와 같은 특수 λ¬Έμžμ™€ μΌμΉ˜ν•˜μ§€λ§Œ β€œa”, β€œ1β€κ³ΌλŠ” μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  6. \s (곡백 문자): 곡백 문자(슀페이슀, νƒ­, μ€„λ°”κΏˆ)와 μΌμΉ˜ν•©λ‹ˆλ‹€.

    • 예: \sλŠ” β€œHello Worldβ€μ—μ„œ 단어 μ‚¬μ΄μ˜ 곡백과 μΌμΉ˜ν•©λ‹ˆλ‹€.
  7. \S (곡백 λ¬Έμžκ°€ μ•„λ‹˜): 곡백 λ¬Έμžκ°€ μ•„λ‹Œ λͺ¨λ“  λ¬Έμžμ™€ μΌμΉ˜ν•©λ‹ˆλ‹€.

    • 예: \SλŠ” β€œHelloβ€μ—μ„œ β€œH”, β€œe”, β€œl”, β€œl”, β€œo”와 각각 μΌμΉ˜ν•˜μ§€λ§Œ κ³΅λ°±κ³ΌλŠ” μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  8. ^ (λ¬Έμžμ—΄μ˜ μ‹œμž‘): λ¬Έμžμ—΄μ˜ μ‹œμž‘ 뢀뢄을 μ˜λ―Έν•©λ‹ˆλ‹€.

    • 예: ^HelloλŠ” β€œHello, World!”와 μΌμΉ˜ν•˜μ§€λ§Œ β€œHe said Helloβ€μ™€λŠ” μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  9. $ (λ¬Έμžμ—΄μ˜ 끝): λ¬Έμžμ—΄μ˜ 끝 뢀뢄을 μ˜λ―Έν•©λ‹ˆλ‹€.

    • 예: World$λŠ” β€œHello, World!”와 μΌμΉ˜ν•˜μ§€λ§Œ β€œWorld is bigβ€κ³ΌλŠ” μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  10. \b (단어 경계): λ‹¨μ–΄μ˜ 경계(단어와 곡백 λ˜λŠ” λΉ„λ¬Έμž 사이)λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.

    • 예: \bcat\bλŠ” β€œcat is hereβ€μ—μ„œ β€œcat”과 μΌμΉ˜ν•˜μ§€λ§Œ, β€œconcatenationβ€μ—μ„œλŠ” μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  11. \B (비단어 경계): 단어 경계가 μ•„λ‹Œ λΆ€λΆ„κ³Ό μΌμΉ˜ν•©λ‹ˆλ‹€.

    • 예: \Bcat\BλŠ” β€œconcatenationβ€μ—μ„œ β€œcat”과 μΌμΉ˜ν•˜μ§€λ§Œ, β€œcat is hereβ€μ—μ„œλŠ” μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  12. [] (문자 μ§‘ν•©): λŒ€κ΄„ν˜Έ μ•ˆμ— μžˆλŠ” 문자 쀑 ν•˜λ‚˜μ™€ μΌμΉ˜ν•©λ‹ˆλ‹€.

    • 예: [abc]λŠ” β€œa”, β€œb”, β€œc” 쀑 ν•˜λ‚˜μ™€ μΌμΉ˜ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, β€œappleβ€μ—μ„œλŠ” β€œa”, β€œcatβ€μ—μ„œλŠ” β€œc”와 μΌμΉ˜ν•©λ‹ˆλ‹€.
  13. * (0회 이상 반볡): μ•žμ˜ λ¬Έμžκ°€ 0번 이상 반볡될 수 μžˆμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.

    • 예: a*λŠ” β€œa”, β€œaa”, β€œaaaβ€μ²˜λŸΌ β€œa”가 0번 이상 λ‚˜μ˜€λŠ” λΆ€λΆ„κ³Ό μΌμΉ˜ν•©λ‹ˆλ‹€.
  14. + (1회 이상 반볡): μ•žμ˜ λ¬Έμžκ°€ 1번 이상 반볡될 수 μžˆμŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.

    • 예: a+λŠ” β€œa”, β€œaa”, β€œaaa”와 μΌμΉ˜ν•˜μ§€λ§Œ, β€œbβ€μ™€λŠ” μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  15. ? (0회 λ˜λŠ” 1회): μ•žμ˜ λ¬Έμžκ°€ 0번 λ˜λŠ” 1번 λ‚˜μ˜€λŠ” 것과 μΌμΉ˜ν•©λ‹ˆλ‹€.

    • 예: a?λŠ” β€œa” λ˜λŠ” 아무 λ¬Έμžλ„ μ—†λŠ” λΆ€λΆ„κ³Ό μΌμΉ˜ν•©λ‹ˆλ‹€.
  16. {n} (μ •ν™•νžˆ n회 반볡): μ•žμ˜ λ¬Έμžκ°€ μ •ν™•νžˆ n번 λ‚˜μ˜€λŠ” 것과 μΌμΉ˜ν•©λ‹ˆλ‹€.

    • 예: a{3}λŠ” β€œaaa”와 μΌμΉ˜ν•˜μ§€λ§Œ, β€œaa”, β€œaaaaβ€μ™€λŠ” μΌμΉ˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
  17. νŒŒμ΄μ¬μ—μ„œ re λͺ¨λ“ˆ μ‚¬μš©ν•˜κΈ°

re λͺ¨λ“ˆμ€ νŒŒμ΄μ¬μ—μ„œ μ •κ·œν‘œν˜„μ‹μ„ μ§€μ›ν•˜λŠ” ν‘œμ€€ λΌμ΄λΈŒλŸ¬λ¦¬μž…λ‹ˆλ‹€. 이λ₯Ό μ‚¬μš©ν•˜λ©΄ λ¬Έμžμ—΄ 검색, 일치 μ—¬λΆ€ 확인, μΉ˜ν™˜ λ“±μ˜ μž‘μ—…μ„ ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

  • re.search(): λ¬Έμžμ—΄ λ‚΄μ—μ„œ μ •κ·œν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•˜λŠ” 첫 번째 μœ„μΉ˜λ₯Ό λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • re.match(): λ¬Έμžμ—΄μ˜ μ‹œμž‘ λΆ€λΆ„μ—μ„œ μ •κ·œν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•˜λŠ”μ§€λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.
  • re.findall(): μ •κ·œν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•˜λŠ” λͺ¨λ“  λΆ€λΆ„ λ¬Έμžμ—΄μ„ 리슀트둜 λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • re.sub(): μ •κ·œν‘œν˜„μ‹μ— μΌμΉ˜ν•˜λŠ” 뢀뢄을 λ‹€λ₯Έ λ¬Έμžμ—΄λ‘œ μΉ˜ν™˜ν•©λ‹ˆλ‹€.
  • re.split(): μ •κ·œν‘œν˜„μ‹μ— 따라 λ¬Έμžμ—΄μ„ λ‚˜λˆ•λ‹ˆλ‹€.
1
2
3
4
5
6
7
8
import re

# κ°„λ‹¨ν•œ 예제
text = "The rain in Spain"

# 'rain'μ΄λΌλŠ” 단어가 μžˆλŠ”μ§€ 검색
result = re.search(r"rain", text)
print(result)  # <re.Match object; span=(4, 8), match='rain'>

3.1 re.search() ν•¨μˆ˜

re.search()λŠ” μ£Όμ–΄μ§„ λ¬Έμžμ—΄μ—μ„œ μ •κ·œν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•˜λŠ” 첫 번째 뢀뢄을 λ°˜ν™˜ν•©λ‹ˆλ‹€. μΌμΉ˜ν•˜λŠ” νŒ¨ν„΄μ΄ μ—†μœΌλ©΄ None을 λ°˜ν™˜ν•©λ‹ˆλ‹€.

1
2
3
4
5
6
7
8
9
# 이메일 ν˜•μ‹ μ°ΎκΈ°
email_text = "My email is example@mail.com"
email_pattern = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\b"

email_match = re.search(email_pattern, email_text)
if email_match:
    print(f"이메일 μ£Όμ†Œ: {email_match.group()}")
else:
    print("이메일 μ£Όμ†Œλ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.")

3.2 re.findall() ν•¨μˆ˜

re.findall() ν•¨μˆ˜λŠ” λ¬Έμžμ—΄ λ‚΄μ—μ„œ μ •κ·œν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•˜λŠ” λͺ¨λ“  λΆ€λΆ„ λ¬Έμžμ—΄μ„ 리슀트둜 λ°˜ν™˜ν•©λ‹ˆλ‹€.

1
2
3
4
5
text = "Call me at 123-456-7890 or 987-654-3210"
phone_pattern = r"\d{3}-\d{3}-\d{4}"

matches = re.findall(phone_pattern, text)
print(matches)  # ['123-456-7890', '987-654-3210']

3.3 re.sub() ν•¨μˆ˜

re.sub() ν•¨μˆ˜λŠ” μ •κ·œν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•˜λŠ” λ¬Έμžμ—΄μ„ λ‹€λ₯Έ λ¬Έμžμ—΄λ‘œ μΉ˜ν™˜ν•˜λŠ” 데 μ‚¬μš©λ©λ‹ˆλ‹€.

1
2
3
text = "My phone number is 123-456-7890."
masked_text = re.sub(r"\d{3}-\d{3}-\d{4}", "XXX-XXX-XXXX", text)
print(masked_text)  # My phone number is XXX-XXX-XXXX.

3.4 re.split() ν•¨μˆ˜

re.split() ν•¨μˆ˜λŠ” μ •κ·œν‘œν˜„μ‹μ„ κΈ°μ€€μœΌλ‘œ λ¬Έμžμ—΄μ„ λ‚˜λˆŒ λ•Œ μœ μš©ν•©λ‹ˆλ‹€.

1
2
3
text = "apple, banana; orange, pineapple"
split_text = re.split(r"[;,]", text)
print(split_text)  # ['apple', ' banana', ' orange', ' pineapple']
  1. μ •κ·œ ν‘œν˜„μ‹ μ˜ˆμ‹œ

πŸ”Ž (μ°Έκ³ ) Notations

  • μ •κ·œν‘œν˜„μ‹ νŒ¨ν„΄μ„ μž‘μ„±ν•  λ•Œ, νŒŒμ΄μ¬μ—μ„œλŠ” μŠ¬λž˜μ‹œ(/)둜 κ°μ‹ΈλŠ” λŒ€μ‹  λ¬Έμžμ—΄ λ¦¬ν„°λŸ΄ r”” μ•ˆμ— μž‘μ„±ν•©λ‹ˆλ‹€. r은 β€œraw string”을 μ˜λ―Έν•˜λ©°, 이 λ°©μ‹μœΌλ‘œ μž‘μ„±ν•˜λ©΄ λ°±μŠ¬λž˜μ‹œ() 같은 특수 λ¬Έμžκ°€ κ·ΈλŒ€λ‘œ μ „λ‹¬λ˜μ–΄ μ •κ·œν‘œν˜„μ‹μ—μ„œ μ˜¬λ°”λ₯΄κ²Œ ν•΄μ„λ©λ‹ˆλ‹€.
    • 파이썬 말고 λ‹¨μˆœ μ •κ·œ ν‘œν˜„μ‹λ§Œμ„ ν‘œκΈ°ν•  λ•Œ, ^κ³Ό $λŠ” λ¬Έμžμ—΄μ˜ μ‹œμž‘κ³Ό 끝을 μ˜λ―Έν•¨.
    • νŒŒμ΄μ¬μ—μ„œλŠ” μ •κ·œν‘œν˜„μ‹μ„ μŠ¬λž˜μ‹œ(/)둜 감싸지 μ•Šκ³ , λ¬Έμžμ—΄ λ¦¬ν„°λŸ΄(r"")둜 μ‚¬μš©.
  • ν”Œλž˜κ·Έ (예: /g): νŒŒμ΄μ¬μ—μ„œλŠ” /g 같은 ν”Œλž˜κ·Έ λŒ€μ‹ , re λͺ¨λ“ˆμ—μ„œ μ˜΅μ…˜μœΌλ‘œ ν”Œλž˜κ·Έλ₯Ό μ „λ‹¬ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄, μ—¬λŸ¬ μ€„μ—μ„œ νŒ¨ν„΄μ„ κ²€μƒ‰ν•˜κ³  μ‹ΆμœΌλ©΄ re.MULTILINE ν”Œλž˜κ·Έλ₯Ό μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.
    • /gλŠ” μ „μ—­ 검색을 μ˜λ―Έν•˜μ§€λ§Œ, νŒŒμ΄μ¬μ—μ„œλŠ” ν•„μš” μ—†μŒ.
    • ν”Œλž˜κ·ΈλŠ” 파이썬의 re λͺ¨λ“ˆμ—μ„œ λ³„λ„λ‘œ μ²˜λ¦¬λ©λ‹ˆλ‹€.

4.1. 이메일 μ£Όμ†Œ 검증

1
/^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$/
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ 이메일 μ£Όμ†Œ ν˜•μ‹μ„ κ²€μ¦ν•˜λŠ”λ° μ‚¬μš©λ©λ‹ˆλ‹€. 이메일은 λ°˜λ“œμ‹œ @ κΈ°ν˜Έκ°€ ν¬ν•¨λ˜μ–΄ 있고, 뒀에 도메인과 μ΅œμƒμœ„ 도메인이 μ˜΅λ‹ˆλ‹€.
    • ^[a-zA-Z0-9._%-]+: 이메일 μ£Όμ†Œμ˜ μ‚¬μš©μž 이름 뢀뢄을 λ§€μΉ­. 문자, 숫자, 밑쀄, 점 등을 ν—ˆμš©ν•˜λ©°, ν•˜λ‚˜ 이상이 λ‚˜μ™€μ•Ό 함.
    • @[a-zA-Z0-9.-]+: @ 뒀에 도메인 이름을 λ§€μΉ­. 문자, 숫자, 점, λŒ€μ‹œλ₯Ό ν—ˆμš©.
    • \.[a-zA-Z]{2,6}$: λ§ˆμ§€λ§‰μœΌλ‘œ μ΅œμƒμœ„ 도메인 뢀뢄을 λ§€μΉ­. 2~6자리의 문자둜 λλ‚˜μ•Ό 함.

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
6
7
8
9
10
import re

email_text = "My email is example@mail.com"
email_pattern = r"^[a-zA-Z0-9._%-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}$"

email_match = re.search(email_pattern, email_text)
if email_match:
    print(f"이메일 μ£Όμ†Œ: {email_match.group()}")
else:
    print("이메일 μ£Όμ†Œλ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.")
  • μ‚¬μš© ν•¨μˆ˜: re.search()λŠ” λ¬Έμžμ—΄ λ‚΄μ—μ„œ νŒ¨ν„΄μ΄ 처음으둜 μΌμΉ˜ν•˜λŠ” 뢀뢄을 μ°ΎμŠ΅λ‹ˆλ‹€. μΌμΉ˜ν•˜λŠ” 뢀뢄이 있으면 Match 객체λ₯Ό λ°˜ν™˜ν•˜κ³ , μ—†μœΌλ©΄ None을 λ°˜ν™˜ν•©λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:

    1
    2
    3
    4
    5
    
    # μž…λ ₯ 1
    email_text = "My email is example@mail.com"
      
    # 좜λ ₯ 1
    이메일 μ£Όμ†Œλ₯Ό 찾을 수 μ—†μŠ΅λ‹ˆλ‹€.
    
    1
    2
    3
    4
    5
    
    # μž…λ ₯ 2
    email_text = "example@mail.com"
      
    # 좜λ ₯ 2
    이메일 μ£Όμ†Œ: example@mail.com  
    

μ™œ λ‹€λ₯Έκ°€?

✍️ 이메일 μ£Όμ†Œ κ²€μ¦μ—μ„œλŠ” μ •κ·œν‘œν˜„μ‹μ— ^(λ¬Έμžμ—΄μ˜ μ‹œμž‘)κ³Ό $(λ¬Έμžμ—΄μ˜ 끝)κ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€. 이 μ˜λ―ΈλŠ” ν•΄λ‹Ή μ •κ·œν‘œν˜„μ‹μ΄ λ¬Έμžμ—΄ 전체가 이메일 ν˜•μ‹κ³Ό μ •ν™•νžˆ μΌμΉ˜ν•΄μ•Όλ§Œ λ§€μΉ­λœλ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 즉, 이메일 이외에 λ‹€λ₯Έ λ¬Έμžμ—΄μ΄ ν¬ν•¨λ˜μ–΄ 있으면 κ·Έ λ¬Έμžμ—΄ 전체가 νŒ¨ν„΄μ— λ§žμ§€ μ•ŠκΈ° λ•Œλ¬Έμ— λ§€μΉ­λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.


4.2. URL λ§€μΉ­

1
/((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)/
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ μ›Ή URL ν˜•μ‹μ„ λ§€μΉ­ν•©λ‹ˆλ‹€. http, https, λ˜λŠ” www둜 μ‹œμž‘ν•˜κ³ , 도메인 이름과 μ„ νƒμ μœΌλ‘œ 쿼리 슀트링, ν”„λž˜κ·Έλ¨ΌνŠΈκ°€ 포함될 수 μžˆμŠ΅λ‹ˆλ‹€. μ˜ˆμ‹œλ‘œ 가져와 λ΄€λŠ”λ° 생각 μ΄μƒμœΌλ‘œ 맀운 λ§›μ΄λ„€μš”πŸŒΆοΈπŸŒΆοΈ(μŠ€ν‚΅ν•˜μ…”λ„ λ©λ‹ˆλ‹€γ…Žγ…Ž) 각각 μƒμ„Έν•˜κ²Œ ν•΄μ„ν•΄λ³΄κ² μŠ΅λ‹ˆλ‹€.

    1. ν”„λ‘œν† μ½œ λ§€μΉ­: ([A-Za-z]{3,9}:(?:\/\/)?)

      • [A-Za-z]{3,9}: 3~9개의 μ•ŒνŒŒλ²³ λ¬Έμžκ°€ ν¬ν•¨λœ λ¬Έμžμ—΄μ„ λ§€μΉ­ν•©λ‹ˆλ‹€. μ΄λŠ” http, https, ftp, mailto와 같은 인터넷 ν”„λ‘œν† μ½œμ„ λ§€μΉ­ν•˜λŠ” λΆ€λΆ„μž…λ‹ˆλ‹€.
      • :: ν”„λ‘œν† μ½œ λ’€μ—λŠ” λ°˜λ“œμ‹œ 콜둠(:)이 λ”°λΌμ˜΅λ‹ˆλ‹€.
      • (?:\/\/)?: 선택적인 //λ₯Ό λ§€μΉ­ν•©λ‹ˆλ‹€. (?:)λŠ” non-capturing group으둜, 이 그룹을 μΊ‘μ²˜ν•˜μ§€λŠ” μ•Šμ§€λ§Œ // μžμ²΄λŠ” μžˆμ–΄μ•Ό ν•˜λŠ” λΆ€λΆ„μž…λ‹ˆλ‹€. κ·ΈλŸ¬λ‚˜ //λŠ” ν•„μˆ˜κ°€ μ•„λ‹ˆκΈ° λ•Œλ¬Έμ— ?λ₯Ό λΆ™μ—¬μ„œ μžˆμ„ μˆ˜λ„ 있고 없을 μˆ˜λ„ μžˆλ„λ‘ ν•©λ‹ˆλ‹€. (Ex. http://, https://, ftp:// 등을 처리)
    2. 도메인 μ‚¬μš©μž 정보 및 도메인 λ§€μΉ­: (?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+

      • (?:[\-;:&=\+\$,\w]+@)?: μ„ νƒμ μœΌλ‘œ μ‚¬μš©μž 정보λ₯Ό 포함할 수 μžˆμŠ΅λ‹ˆλ‹€.

        • 예λ₯Ό λ“€μ–΄ user:password@처럼 도메인 이전에 μ‚¬μš©μž 이름과 λΉ„λ°€λ²ˆν˜Έλ₯Ό ν¬ν•¨ν•˜λŠ” κ²½μš°κ°€ μžˆμŠ΅λ‹ˆλ‹€.
        • [\-;:&=\+\$,\w]+: 이 λΆ€λΆ„μ—μ„œ μ‚¬μš©μž 정보와 κ΄€λ ¨λœ λ‹€μ–‘ν•œ 문자λ₯Ό ν—ˆμš©ν•©λ‹ˆλ‹€.
          • \wλŠ” μ•ŒνŒŒλ²³, 숫자, 밑쀄을 μ˜λ―Έν•©λ‹ˆλ‹€.
          • \-;:&=\+\$λŠ” ν—ˆμš©λœ νŠΉμˆ˜λ¬Έμžλ“€μž…λ‹ˆλ‹€.
        • @λŠ” λ°˜λ“œμ‹œ μžˆμ–΄μ•Ό ν•˜λ©°, μ‚¬μš©μž 정보 뒀에 λ‚˜μ˜€λŠ” @ 기호λ₯Ό μ²˜λ¦¬ν•©λ‹ˆλ‹€. 이 뢀뢄은 선택적이기 λ•Œλ¬Έμ— ?κ°€ 뒀에 λΆ™μ–΄ μžˆμŠ΅λ‹ˆλ‹€.
      • [A-Za-z0-9\.\-]+: μ‹€μ œ 도메인 이름을 λ§€μΉ­ν•©λ‹ˆλ‹€.

        • [A-Za-z0-9]: 도메인은 λ¬Έμžμ™€ 숫자둜 μ΄λ£¨μ–΄μ§ˆ 수 μžˆμŠ΅λ‹ˆλ‹€.
        • \.: 도메인 이름 내에 점(.)이 포함될 수 μžˆμŠ΅λ‹ˆλ‹€.
          • 예λ₯Ό λ“€μ–΄, example.comμ—μ„œμ˜ 점을 μ²˜λ¦¬ν•˜λŠ” λΆ€λΆ„μž…λ‹ˆλ‹€.
        • \-: 도메인 이름 내에 ν•˜μ΄ν”ˆ(-)이 포함될 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
          • 예λ₯Ό λ“€μ–΄, my-site.com 같은 도메인을 μ²˜λ¦¬ν•©λ‹ˆλ‹€.
    3. www λ§€μΉ­ λ˜λŠ” μ‚¬μš©μž 정보 포함 κ°€λŠ₯: (?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+

      • (?:www\.): www.둜 μ‹œμž‘ν•˜λŠ” 도메인을 λ§€μΉ­ν•©λ‹ˆλ‹€.
        • μ—¬κΈ°μ„œ non-capturing group을 μ‚¬μš©ν•œ 것은 www.λŠ” μžˆμ§€λ§Œ λ°˜λ“œμ‹œ μΊ‘μ²˜ν•  ν•„μš”κ°€ μ—†λŠ” 뢀뢄이기 λ•Œλ¬Έμž…λ‹ˆλ‹€.
      • |[\-;:&=\+\$,\w]+@: λ˜λŠ” μ‚¬μš©μž 정보가 ν¬ν•¨λœ ν˜•νƒœ(μ•žμ„œ μ„€λͺ…ν•œ λΆ€λΆ„μ²˜λŸΌ user:password@)λ₯Ό μ²˜λ¦¬ν•©λ‹ˆλ‹€.
    4. 경둜 맀칭: ((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?

      1. (?:\/[\+~%\/\.\w\-_]*)?: URL의 경둜 처리

        • \/: μŠ¬λž˜μ‹œ(/)둜 μ‹œμž‘ν•˜λŠ” 경둜λ₯Ό λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
          • 예λ₯Ό λ“€μ–΄, /path/to/resource와 같은 κ²½λ‘œμž…λ‹ˆλ‹€.
        • [\+~%\/\.\w\-_]*: 경둜 내에 ν—ˆμš©λ˜λŠ” λ‹€μ–‘ν•œ 문자λ₯Ό μ²˜λ¦¬ν•©λ‹ˆλ‹€.
          • \w: μ•ŒνŒŒλ²³, 숫자, 밑쀄(_)을 μ˜λ―Έν•©λ‹ˆλ‹€.
          • \-: ν•˜μ΄ν”ˆ(-).
          • \., \/, \+, %: κ²½λ‘œμ— 자주 λ‚˜νƒ€λ‚˜λŠ” 특수 λ¬Έμžμž…λ‹ˆλ‹€.
        • ?: 이 전체 그룹은 μ„ νƒμ μ΄λ―€λ‘œ, κ²½λ‘œκ°€ 없을 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
      2. \??: 쿼리 슀트링 처리

        • ?: μ„ νƒμ μœΌλ‘œ 쿼리 슀트링이 뢙을 수 μžˆμŠ΅λ‹ˆλ‹€.
          • 예λ₯Ό λ“€μ–΄, ?key=value 같은 ν˜•νƒœμž…λ‹ˆλ‹€.
        • \?λŠ” μ‹€μ œ 쿼리 슀트링의 μ‹œμž‘μ„ λ‚˜νƒ€λ‚΄λŠ” λ¬ΌμŒν‘œ(?)λ₯Ό λ§€μΉ­ν•©λ‹ˆλ‹€.
        • ?λŠ” λ¬ΌμŒν‘œκ°€ μžˆμ„ μˆ˜λ„ 없을 μˆ˜λ„ μžˆμŒμ„ λ‚˜νƒ€λƒ…λ‹ˆλ‹€.
      3. (?:[\-\+=&;%@\.\w_]*): 쿼리 슀트링 처리

        • 쿼리 슀트링의 ν‚€-κ°’ μŒμ—μ„œ ν—ˆμš©λ˜λŠ” λ‹€μ–‘ν•œ 문자λ₯Ό μ²˜λ¦¬ν•©λ‹ˆλ‹€.
        • [\-\+=&;%@\.\w_]*: 쿼리 μŠ€νŠΈλ§μ— 포함될 수 μžˆλŠ” λ¬Έμžμž…λ‹ˆλ‹€.
          • 예λ₯Ό λ“€μ–΄, key=value&anotherKey=value2처럼 λ³΅μž‘ν•œ ν˜•νƒœμ˜ 쿼리 μŠ€νŠΈλ§μ„ μ²˜λ¦¬ν•©λ‹ˆλ‹€.
      4. #?(?:[\.\!\/\\\w]*): ν•΄μ‹œ ν”„λž˜κ·Έλ¨ΌνŠΈ 처리

        • #?: ν•΄μ‹œ ν”„λž˜κ·Έλ¨ΌνŠΈλ₯Ό μ„ νƒμ μœΌλ‘œ μ²˜λ¦¬ν•©λ‹ˆλ‹€. ν•΄μ‹œ 기호(#)λŠ” μžˆμ„ μˆ˜λ„, 없을 μˆ˜λ„ μžˆμŠ΅λ‹ˆλ‹€.
        • (?:[\.\!\/\\\w]*): ν•΄μ‹œ ν”„λž˜κ·Έλ¨ΌνŠΈ 내에 포함될 수 μžˆλŠ” λ¬Έμžμž…λ‹ˆλ‹€. ν•΄μ‹œ λ’€μ—λŠ” 일반적으둜 μ•ŒνŒŒλ²³, 숫자, μŠ¬λž˜μ‹œ 등이 ν¬ν•¨λ©λ‹ˆλ‹€.
          • 예λ₯Ό λ“€μ–΄ #section1 같은 ν˜•νƒœλ₯Ό μ²˜λ¦¬ν•©λ‹ˆλ‹€.

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
6
7
8
import re

text = "Visit us at https://www.example.com or http://example.org"
url_pattern = r"((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)"

urls = re.findall(url_pattern, text)
for url in urls:
    print(f"URL: {url[0]}")
  • μ‚¬μš© ν•¨μˆ˜: re.findall()은 λ¬Έμžμ—΄ λ‚΄μ—μ„œ νŒ¨ν„΄κ³Ό μΌμΉ˜ν•˜λŠ” λͺ¨λ“  뢀뢄을 리슀트둜 λ°˜ν™˜ν•©λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:
    1
    2
    
    URL: https://www.example.com
    URL: http://example.org
    

4.3. μ „ν™”λ²ˆν˜Έ (ν•œκ΅­ νœ΄λŒ€ν° 번호 ν˜•μ‹)

1
/010-\d{4}-\d{4}/
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ ν•œκ΅­μ˜ ν‘œμ€€μ μΈ νœ΄λŒ€μ „ν™” 번호 ν˜•μ‹μ„ λ§€μΉ­ν•©λ‹ˆλ‹€.
    • 010-: μ „ν™”λ²ˆν˜ΈλŠ” 항상 β€œ010-β€œμœΌλ‘œ μ‹œμž‘ν•©λ‹ˆλ‹€.
    • \d{4}-\d{4}: 각각 4자리의 μˆ«μžκ°€ λ‚˜μ˜€λ©°, ν•˜μ΄ν”ˆ(-)으둜 κ΅¬λΆ„λ©λ‹ˆλ‹€.

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
6
7
import re

text = "μ—°λ½μ²˜λŠ” 010-1234-5678 λ˜λŠ” 010-9876-5432μž…λ‹ˆλ‹€."
phone_pattern = r"010-\d{4}-\d{4}"

matches = re.findall(phone_pattern, text)
print(matches)  # ['010-1234-5678', '010-9876-5432']
  • μ‚¬μš© ν•¨μˆ˜: re.findall()은 λ¬Έμžμ—΄ λ‚΄μ—μ„œ νŒ¨ν„΄κ³Ό μΌμΉ˜ν•˜λŠ” λͺ¨λ“  μ „ν™”λ²ˆν˜Έλ₯Ό 리슀트둜 λ°˜ν™˜ν•©λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:
    1
    
    ['010-1234-5678', '010-9876-5432']
    

4.4. λ‚ μ§œ ν˜•μ‹ (MM/DD/YYYY)

1
/^[0-3]?[0-9](?:\/|\.|-)[0-3]?[0-9](?:\/|\.|-)[1-9]\d{3}$/
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ MM/DD/YYYY ν˜•μ‹μ˜ λ‚ μ§œλ₯Ό λ§€μΉ­ν•©λ‹ˆλ‹€.
    • [0-3]?[0-9]: 첫 번째 두 μžλ¦¬λŠ” λ‚ μ§œμ˜ 일(day)을 μ˜λ―Έν•©λ‹ˆλ‹€.
    • (?:\/|\.|-): ꡬ뢄 기호λ₯Ό μΊ‘μ²˜ν•˜μ§€ μ•Šλ„λ‘ non-capturing group을 μ‚¬μš©ν•©λ‹ˆλ‹€.
      • 이 λΆ€λΆ„μ—μ„œ ꡬ뢄 기호(\/, ., -)λŠ” μ—¬μ „νžˆ λ§€μΉ­λ˜μ§€λ§Œ μΊ‘μ²˜λ˜μ§€ μ•ŠμœΌλ―€λ‘œ 결과에 ν¬ν•¨λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
    • [0-3]?[0-9]: 두 번째 두 μžλ¦¬λŠ” μ›”(month)을 μ˜λ―Έν•©λ‹ˆλ‹€.
    • (?:\/|\.|-): λ‹€μ‹œ non-capturing group을 μ‚¬μš©ν•˜μ—¬ ꡬ뢄 기호λ₯Ό 맀칭만 ν•˜κ³  μΊ‘μ²˜ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.
    • [1-9]\d{3}: λ§ˆμ§€λ§‰μœΌλ‘œ 연도(year)λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. 1000λ…„ μ΄ν›„μ˜ λ„€ 자리 숫자λ₯Ό λ§€μΉ­ν•©λ‹ˆλ‹€.

(μš©μ–΄) Capturing & Non-Capturing Group

  • Capturing Group: ( ) μ•ˆμ— μ •μ˜λœ νŒ¨ν„΄μ„ μΊ‘μ²˜ν•˜κ³  결과둜 λ°˜ν™˜ν•©λ‹ˆλ‹€.
  • Non-Capturing Group: ( ? : ) μ•ˆμ— μ •μ˜λœ νŒ¨ν„΄μ„ μΊ‘μ²˜ν•˜μ§€ μ•Šκ³ , νŒ¨ν„΄ 맀칭의 μΌλΆ€λΆ„μœΌλ‘œλ§Œ μ‚¬μš©ν•©λ‹ˆλ‹€. 결과에 ν¬ν•¨λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

(μš©μ–΄) νŒ¨ν„΄μ„ μΊ‘μ³ν•œλ‹€κ³ ?

  • μ •κ·œν‘œν˜„μ‹μ—μ„œ 캑처 그룹을 μ‚¬μš©ν•˜λ©΄, μ†Œκ΄„ν˜Έ () μ•ˆμ— λ“€μ–΄μžˆλŠ” 뢀뢄을 결과에 ν¬ν•¨ν•˜κ±°λ‚˜, κ·Έλ£Ήλ³„λ‘œ λ”°λ‘œ μ‚¬μš©ν•  수 μžˆλŠ” ν˜•νƒœλ‘œ μ²˜λ¦¬ν•©λ‹ˆλ‹€.
    • 캑처 그룹은 맀칭된 κ²°κ³Όλ₯Ό λ³„λ„λ‘œ μ €μž₯ν•˜κ±°λ‚˜, λ‚˜μ€‘μ— λ‹€μ‹œ μ‚¬μš©ν•  수 μžˆλŠ” νŠΉλ³„ν•œ κΈ°λŠ₯을 μ œκ³΅ν•©λ‹ˆλ‹€.
    • 캑처 그룹은 μ •κ·œν‘œν˜„μ‹μ—μ„œ 맀칭된 뢀뢄을 λ³„λ„λ‘œ μ €μž₯ν•˜κ±°λ‚˜, λ‚˜μ€‘μ— μ°Έμ‘°ν•  수 있게 ν•΄μ€λ‹ˆλ‹€.
      • 예λ₯Ό λ“€μ–΄, re.findall()은 캑처 그룹이 μžˆλ‹€λ©΄ ν•΄λ‹Ή 그룹의 일치 ν•­λͺ©λ§Œ 결과둜 λ°˜ν™˜ν•©λ‹ˆλ‹€.
        1
        2
        3
        4
        5
        
        import re
        text = "My email is example@mail.com"
        email_pattern = r"([a-zA-Z0-9._%-]+)@([a-zA-Z0-9.-]+\.[a-zA-Z]{2,6})"
        matches = re.findall(email_pattern, text)
        print(matches)  # [('example', 'mail.com')]
        
        • μ—¬κΈ°μ„œ ([a-zA-Z0-9._%-]+): μ΄λ©”μΌμ˜ μ‚¬μš©μž 이름 뢀뢄을 μΊ‘μ²˜ν•©λ‹ˆλ‹€.
        • ([a-zA-Z0-9.-]+\.[a-zA-Z]{2,6}): 도메인 뢀뢄을 μΊ‘μ²˜ν•©λ‹ˆλ‹€.
        • κ²°κ³ΌλŠ” 두 개의 그룹으둜 λΆ„λ¦¬λ˜μ–΄ λ°˜ν™˜λ©λ‹ˆλ‹€: (β€˜example’, β€˜mail.com’).
  • λ°˜λŒ€λ‘œ, non-capturing group((?: ...))은 ν•΄λ‹Ή νŒ¨ν„΄μ„ λ§€μΉ­ν•˜λ˜ 결과둜 λ°˜ν™˜ν•˜μ§€ μ•Šκ³ , 단지 νŒ¨ν„΄μ„ κ΅¬μ„±ν•˜λŠ” μš”μ†Œλ‘œλ§Œ μ‚¬μš©λ©λ‹ˆλ‹€.
    1
    2
    3
    4
    5
    
    import re
    text = "My email is example@mail.com"
    email_pattern = r"(?:[a-zA-Z0-9._%-]+)@(?:[a-zA-Z0-9.-]+\.[a-zA-Z]{2,6})"
    matches = re.findall(email_pattern, text)
    print(matches)  # ['example@mail.com']
    
    • μ—¬κΈ°μ„œ μΊ‘μ²˜ν•˜μ§€ μ•ŠλŠ” κ·Έλ£Ή (?: ...)λ₯Ό μ‚¬μš©ν•˜μ˜€κΈ° λ•Œλ¬Έμ—, μ΄λ©”μΌμ˜ 뢀뢄을 μΊ‘μ²˜ν•˜μ§€ μ•Šκ³ , 전체 μ΄λ©”μΌλ§Œ λ§€μΉ­ν•˜κ³  결과둜 λ°˜ν™˜ν•©λ‹ˆλ‹€: β€˜example@mail.com’

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
6
7
8
9
import re

text = "The event is on 12/25/2024 or 01-01-2025."

# 캑처 그룹을 non-capturing group으둜 λ³€κ²½
date_pattern = r"[0-3]?[0-9](?:\/|\.|-)[0-3]?[0-9](?:\/|\.|-)[1-9]\d{3}"

dates = re.findall(date_pattern, text)
print(dates)  # ['12/25/2024', '01-01-2025']
  • μ‚¬μš© ν•¨μˆ˜: re.findall()은 λ¬Έμžμ—΄ λ‚΄μ—μ„œ νŒ¨ν„΄κ³Ό μΌμΉ˜ν•˜λŠ” λͺ¨λ“  λ‚ μ§œλ₯Ό 리슀트둜 λ°˜ν™˜ν•©λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:
    1
    
    ['12/25/2024', '01-01-2025']
    

4.5. κ°•λ ₯ν•œ λΉ„λ°€λ²ˆν˜Έ 검증

1
/^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{10,}$/
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ λŒ€λ¬Έμž, μ†Œλ¬Έμž, 숫자, 특수 문자λ₯Ό λͺ¨λ‘ ν¬ν•¨ν•œ μ΅œμ†Œ 10자리의 κ°•λ ₯ν•œ λΉ„λ°€λ²ˆν˜Έλ₯Ό λ§€μΉ­ν•©λ‹ˆλ‹€.
    • (?=.*[a-z]): μ†Œλ¬Έμž μ΅œμ†Œ ν•˜λ‚˜κ°€ ν¬ν•¨λ˜μ–΄μ•Ό 함.
    • (?=.*[A-Z]): λŒ€λ¬Έμž μ΅œμ†Œ ν•˜λ‚˜κ°€ ν¬ν•¨λ˜μ–΄μ•Ό 함.
    • (?=.*\d): 숫자 μ΅œμ†Œ ν•˜λ‚˜κ°€ ν¬ν•¨λ˜μ–΄μ•Ό 함.
    • (?=.*[@$!%*?&]): 특수 문자 μ΅œμ†Œ ν•˜λ‚˜κ°€ ν¬ν•¨λ˜μ–΄μ•Ό 함.
    • [A-Za-z\d@$!%*?&]{10,}: μœ„ 쑰건을 λ§Œμ‘±ν•˜λ©° 10자리 이상이어야 함.

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
6
7
8
9
import re

password = "StrongP@ssword1"
password_pattern = r"^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[@$!%*?&])[A-Za-z\d@$!%*?&]{10,}$"

if re.match(password_pattern, password):
    print("λΉ„λ°€λ²ˆν˜Έκ°€ μœ νš¨ν•©λ‹ˆλ‹€.")
else:
    print("λΉ„λ°€λ²ˆν˜Έκ°€ μœ νš¨ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.")
  • μ‚¬μš© ν•¨μˆ˜: re.match()λŠ” λ¬Έμžμ—΄μ˜ μ‹œμž‘λΆ€ν„° μ •κ·œν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•˜λŠ”μ§€λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:
    1
    
    λΉ„λ°€λ²ˆν˜Έκ°€ μœ νš¨ν•©λ‹ˆλ‹€.
    

4.6. μ‚¬μš©μžλͺ… 검증 (μ•ŒνŒŒλ²³κ³Ό 숫자, νŠΉμ • 길이)

1
/^[a-zA-Z0-9_-]{3,16}$/
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ 3~16자의 μ•ŒνŒŒλ²³, 숫자, 밑쀄 λ˜λŠ” λŒ€μ‹œλ‘œ κ΅¬μ„±λœ μ‚¬μš©μžλͺ…을 λ§€μΉ­ν•©λ‹ˆλ‹€.
    • [a-zA-Z0-9_-]: μ•ŒνŒŒλ²³, 숫자, 밑쀄, λŒ€μ‹œλ₯Ό ν—ˆμš©ν•©λ‹ˆλ‹€.
    • {3,16}: μ΅œμ†Œ 3자, μ΅œλŒ€ 16μžκΉŒμ§€ ν—ˆμš©ν•©λ‹ˆλ‹€.

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
6
7
8
9
import re

username = "user_name123"
username_pattern = r"^[a-zA-Z0-9_-]{3,16}$"

if re.match(username_pattern, username):
    print("μ‚¬μš©μžλͺ…이 μœ νš¨ν•©λ‹ˆλ‹€.")
else:
    print("μ‚¬μš©μžλͺ…이 μœ νš¨ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.")
  • μ‚¬μš© ν•¨μˆ˜: re.match()λŠ” λ¬Έμžμ—΄μ˜ μ‹œμž‘λΆ€ν„° μ •κ·œν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•˜λŠ”μ§€λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:
    1
    
    μ‚¬μš©μžλͺ…이 μœ νš¨ν•©λ‹ˆλ‹€.
    

4.7. IP μ£Όμ†Œ 검증 (IPv4 ν˜•μ‹)

1
/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ IPv4 ν˜•μ‹μ˜ IP μ£Όμ†Œλ₯Ό λ§€μΉ­ν•©λ‹ˆλ‹€.
    • 25[0-5]: 250~255 λ²”μœ„μ˜ 숫자.
    • 2[0-4][0-9]: 200~249 λ²”μœ„μ˜ 숫자.
    • [01]?[0-9][0-9]?: 0~199 λ²”μœ„μ˜ 숫자.
    • \.: 각 숫자 ꡬ간은 점(.)으둜 κ΅¬λΆ„λ©λ‹ˆλ‹€.

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
6
7
8
9
import re

ip = "192.168.0.1"
ip_pattern = r"^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$"

if re.match(ip_pattern, ip):
    print("IP μ£Όμ†Œκ°€ μœ νš¨ν•©λ‹ˆλ‹€.")
else:
    print("IP μ£Όμ†Œκ°€ μœ νš¨ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.")
  • μ‚¬μš© ν•¨μˆ˜: re.match()λŠ” λ¬Έμžμ—΄μ˜ μ‹œμž‘λΆ€ν„° μ •κ·œν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•˜λŠ”μ§€λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:
    1
    
    IP μ£Όμ†Œκ°€ μœ νš¨ν•©λ‹ˆλ‹€.
    

4.8. 숫자만 ν—ˆμš©

1
/^\d+$/
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ 숫자둜만 κ΅¬μ„±λœ λ¬Έμžμ—΄μ„ λ§€μΉ­ν•©λ‹ˆλ‹€.
    • ^\d+$: 숫자(\d)κ°€ 1회 이상 (+) 반볡되며, λ¬Έμžμ—΄μ˜ μ‹œμž‘(^)κ³Ό 끝($)이 μˆ«μžμ—¬μ•Ό 함.

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
6
7
8
9
import re

text = "12345"
number_pattern = r"^\d+$"

if re.match(number_pattern, text):
    print("숫자만 ν¬ν•¨λœ λ¬Έμžμ—΄μž…λ‹ˆλ‹€.")
else:
    print("숫자만 ν¬ν•¨λ˜μ§€ μ•Šμ€ λ¬Έμžμ—΄μž…λ‹ˆλ‹€.")
  • μ‚¬μš© ν•¨μˆ˜: re.match()λŠ” λ¬Έμžμ—΄μ˜ μ‹œμž‘λΆ€ν„° μ •κ·œν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•˜λŠ”μ§€λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:
    1
    
    숫자만 ν¬ν•¨λœ λ¬Έμžμ—΄μž…λ‹ˆλ‹€.
    

4.9. μ•ŒνŒŒλ²³κ³Ό 숫자만 ν—ˆμš© (곡백 없이)

1
/^[a-zA-Z0-9]*$/
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ 곡백 없이 μ•ŒνŒŒλ²³κ³Ό 숫자둜만 이루어진 λ¬Έμžμ—΄μ„ λ§€μΉ­ν•©λ‹ˆλ‹€.
    • [a-zA-Z0-9]: μ•ŒνŒŒλ²³ λŒ€μ†Œλ¬Έμžμ™€ 숫자.
    • *: 0회 이상 λ°˜λ³΅μ„ ν—ˆμš©.

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
6
7
8
9
import re

text = "Hello123"
alnum_pattern = r"^[a-zA-Z0-9]*$"

if re.match(alnum_pattern, text):
    print("μ•ŒνŒŒλ²³κ³Ό 숫자둜만 κ΅¬μ„±λœ λ¬Έμžμ—΄μž…λ‹ˆλ‹€.")
else:
    print("λ¬Έμžμ—΄μ— λ‹€λ₯Έ λ¬Έμžκ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.")
  • μ‚¬μš© ν•¨μˆ˜: re.match()λŠ” λ¬Έμžμ—΄μ˜ μ‹œμž‘λΆ€ν„° μ •κ·œν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•˜λŠ”μ§€λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:
    1
    
    μ•ŒνŒŒλ²³κ³Ό 숫자둜만 κ΅¬μ„±λœ λ¬Έμžμ—΄μž…λ‹ˆλ‹€.
    

4.10. μ‹ μš©μΉ΄λ“œ 번호 검증

1
/^(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|622((12[6-9]|1[3-9][0-9])|([2-8][0-9][0-9])|(9(([0-1][0-9])|(2[0-5]))))[0-9]{10}|64[4-9][0-9]{13}|65[0-9]{14}|3(?:0[0-5]|[68][0-9])[0-9]{11}|3[47][0-9]{13})*$/
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ λ‹€μ–‘ν•œ μ‹ μš©μΉ΄λ“œ ν˜•μ‹μ„ λ§€μΉ­ν•©λ‹ˆλ‹€. λΉ„μž, λ§ˆμŠ€ν„°μΉ΄λ“œ, λ””μŠ€μ»€λ²„ μΉ΄λ“œ 등을 검증할 수 μžˆμŠ΅λ‹ˆλ‹€.
    • 4[0-9]{12}(?:[0-9]{3})?: λΉ„μž μΉ΄λ“œ.
    • 5[1-5][0-9]{14}: λ§ˆμŠ€ν„°μΉ΄λ“œ.
    • 6011[0-9]{12}: λ””μŠ€μ»€λ²„ μΉ΄λ“œ.
    • 65[0-9]{14}: 또 λ‹€λ₯Έ μΉ΄λ“œ ν˜•μ‹.

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
6
7
8
9
10
import re

text = "My card number is 4111-1111-1111-1111"
card_pattern = r"(?:4[0-9]{12}(?:[0-9]{3})?|5[1-5][0-9]{14}|6011[0-9]{12}|65[0-9]{14})"

card_match = re.search(card_pattern, text.replace("-", ""))
if card_match:
    print("μ‹ μš©μΉ΄λ“œ λ²ˆν˜Έκ°€ μœ νš¨ν•©λ‹ˆλ‹€.")
else:
    print("μ‹ μš©μΉ΄λ“œ λ²ˆν˜Έκ°€ μœ νš¨ν•˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.")
  • μ‚¬μš© ν•¨μˆ˜: re.search()λŠ” λ¬Έμžμ—΄ λ‚΄μ—μ„œ νŒ¨ν„΄μ΄ μΌμΉ˜ν•˜λŠ” 뢀뢄을 μ°ΎμŠ΅λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:
    1
    
    μ‹ μš©μΉ΄λ“œ λ²ˆν˜Έκ°€ μœ νš¨ν•©λ‹ˆλ‹€.
    

4.11. ν•œκΈ€λ§Œ ν¬ν•¨ν•˜λŠ” λ¬Έμžμ—΄ 검사

1
/^[κ°€-힣]+$/
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ ν•œκΈ€ 문자만으둜 이루어진 λ¬Έμžμ—΄μ„ λ§€μΉ­ν•©λ‹ˆλ‹€.
    • [κ°€-힣]: ν•œκΈ€ μ™„μ„±ν˜• λ²”μœ„λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
6
7
8
9
import re

text = "μ•ˆλ…•ν•˜μ„Έμš”"
hangul_pattern = r"^[κ°€-힣]+$"

if re.match(hangul_pattern, text):
    print("ν•œκΈ€λ‘œλ§Œ 이루어진 λ¬Έμžμ—΄μž…λ‹ˆλ‹€.")
else:
    print("ν•œκΈ€ μ΄μ™Έμ˜ λ¬Έμžκ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.")
  • μ‚¬μš© ν•¨μˆ˜: re.match()λŠ” λ¬Έμžμ—΄μ˜ μ‹œμž‘λΆ€ν„° μ •κ·œν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•˜λŠ”μ§€λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:

    1
    
    ν•œκΈ€λ‘œλ§Œ 이루어진 λ¬Έμžμ—΄μž…λ‹ˆλ‹€.
    

4.12. ν•œκΈ€ 포함 μ—¬λΆ€ 검사

1
/[κ°€-힣]/
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ λ¬Έμžμ—΄μ— ν•œκΈ€μ΄ ν¬ν•¨λ˜μ–΄ μžˆλŠ”μ§€ μ—¬λΆ€λ₯Ό κ²€μ‚¬ν•©λ‹ˆλ‹€.
    • [κ°€-힣]: ν•œκΈ€ μ™„μ„±ν˜• 문자λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€.

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
6
7
8
9
import re

text = "Hello, μ•ˆλ…•ν•˜μ„Έμš”!"
hangul_included_pattern = r"[κ°€-힣]"

if re.search(hangul_included_pattern, text):
    print("λ¬Έμžμ—΄μ— ν•œκΈ€μ΄ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.")
else:
    print("λ¬Έμžμ—΄μ— ν•œκΈ€μ΄ ν¬ν•¨λ˜μ–΄ μžˆμ§€ μ•ŠμŠ΅λ‹ˆλ‹€.")
  • μ‚¬μš© ν•¨μˆ˜: re.search()λŠ” λ¬Έμžμ—΄ λ‚΄μ—μ„œ νŒ¨ν„΄μ΄ 처음으둜 μΌμΉ˜ν•˜λŠ” 뢀뢄을 μ°ΎμŠ΅λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:
    1
    
    λ¬Έμžμ—΄μ— ν•œκΈ€μ΄ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.
    

4.13. μ™„μ„±ν˜• ν•œκΈ€ 검사 (자음, λͺ¨μŒ μ œμ™Έ)

1
/^[κ°€-힣]*$/
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ μ™„μ„±ν˜• ν•œκΈ€λ‘œλ§Œ κ΅¬μ„±λœ λ¬Έμžμ—΄μ„ λ§€μΉ­ν•©λ‹ˆλ‹€. 자음 λ˜λŠ” λͺ¨μŒλ§ŒμœΌλ‘œ 이루어진 λ¬Έμžμ—΄μ€ λ§€μΉ­λ˜μ§€ μ•ŠμŠ΅λ‹ˆλ‹€.

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
6
7
8
9
import re

text = "κ°€λ‚˜λ‹€λΌλ§ˆλ°”μ‚¬"
hangul_complete_pattern = r"^[κ°€-힣]*$"

if re.match(hangul_complete_pattern, text):
    print("μ™„μ„±ν˜• ν•œκΈ€λ‘œλ§Œ 이루어진 λ¬Έμžμ—΄μž…λ‹ˆλ‹€.")
else:
    print("μ™„μ„±ν˜• ν•œκΈ€ μ™Έμ˜ λ¬Έμžκ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.")
  • μ‚¬μš© ν•¨μˆ˜: re.match()λŠ” λ¬Έμžμ—΄μ˜ μ‹œμž‘λΆ€ν„° μ •κ·œν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•˜λŠ”μ§€λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:
    1
    
    μ™„μ„±ν˜• ν•œκΈ€λ‘œλ§Œ 이루어진 λ¬Έμžμ—΄μž…λ‹ˆλ‹€.
    

4.14. ν•œκΈ€, 자음, λͺ¨μŒ λͺ¨λ‘ 포함

1
/^[γ„±-γ…Žγ…-γ…£κ°€-힣]*$/
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ ν•œκΈ€, 자음, λͺ¨μŒμ΄ λͺ¨λ‘ ν¬ν•¨λœ λ¬Έμžμ—΄μ„ λ§€μΉ­ν•©λ‹ˆλ‹€.
    • [γ„±-γ…Žγ…-γ…£κ°€-힣]: ν•œκΈ€ 자음, λͺ¨μŒ, μ™„μ„±ν˜• 문자λ₯Ό λͺ¨λ‘ 포함.

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
6
7
8
9
import re

text = "γ…γ„±ν•˜"
hangul_full_pattern = r"^[γ„±-γ…Žγ…-γ…£κ°€-힣]*$"

if re.match(hangul_full_pattern, text):
    print("ν•œκΈ€(자음, λͺ¨μŒ 포함)둜만 이루어진 λ¬Έμžμ—΄μž…λ‹ˆλ‹€.")
else:
    print("ν•œκΈ€ μ΄μ™Έμ˜ λ¬Έμžκ°€ ν¬ν•¨λ˜μ–΄ μžˆμŠ΅λ‹ˆλ‹€.")
  • μ‚¬μš© ν•¨μˆ˜: re.match()λŠ” λ¬Έμžμ—΄μ˜ μ‹œμž‘λΆ€ν„° μ •κ·œν‘œν˜„μ‹κ³Ό μΌμΉ˜ν•˜λŠ”μ§€λ₯Ό ν™•μΈν•©λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:
    1
    
    ν•œκΈ€(자음, λͺ¨μŒ 포함)둜만 이루어진 λ¬Έμžμ—΄μž…λ‹ˆλ‹€.
    

4.15. 문자λ₯Ό μ œμ™Έν•œ 특수 기호 제거

1
/[^a-zA-Z0-9κ°€-힣\s]/g
  • μ„€λͺ…: 이 μ •κ·œν‘œν˜„μ‹μ€ μ•ŒνŒŒλ²³, 숫자, ν•œκΈ€, 곡백을 μ œμ™Έν•œ λͺ¨λ“  특수 문자λ₯Ό μ œκ±°ν•©λ‹ˆλ‹€.
    • [^a-zA-Z0-9κ°€-힣\s]: μ•ŒνŒŒλ²³, 숫자, ν•œκΈ€, 곡백을 μ œμ™Έν•œ λͺ¨λ“  문자λ₯Ό 의미.

Pythonμ—μ„œμ˜ μ‚¬μš© μ˜ˆμ‹œλŠ” λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€.

1
2
3
4
5
import re

text = "μ•ˆλ…•ν•˜μ„Έμš”! Hello, World! 123 @#$%^&*"
cleaned_text = re.sub(r'[^a-zA-Z0-9κ°€-힣\s]', '', text)
print(cleaned_text)  # 좜λ ₯: μ•ˆλ…•ν•˜μ„Έμš” Hello World 123
  • μ‚¬μš© ν•¨μˆ˜: re.sub()λŠ” μ •κ·œν‘œν˜„μ‹μ— μΌμΉ˜ν•˜λŠ” λͺ¨λ“  뢀뢄을 μ§€μ •ν•œ λ¬Έμžμ—΄λ‘œ μΉ˜ν™˜ν•©λ‹ˆλ‹€.

  • 좜λ ₯ κ²°κ³Ό:
    1
    
    μ•ˆλ…•ν•˜μ„Έμš” Hello World 123
    
  1. 마치며

파이썬의 re λͺ¨λ“ˆκ³Ό μ •κ·œν‘œν˜„μ‹μ„ ν™œμš©ν•˜λ©΄ λ³΅μž‘ν•œ λ¬Έμžμ—΄ 처리λ₯Ό μ†μ‰½κ²Œ ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 이번 ν¬μŠ€νŠΈμ—μ„œ 닀룬 기본적인 μ •κ·œν‘œν˜„μ‹ νŒ¨ν„΄κ³Ό re λͺ¨λ“ˆμ˜ ν•¨μˆ˜λ“€μ„ 잘 ν™œμš©ν•˜λ©΄ λ‹€μ–‘ν•œ ν…μŠ€νŠΈ λ°μ΄ν„°μ—μ„œ νŒ¨ν„΄μ„ μ°Ύμ•„λ‚΄κ³ , λ³€ν˜•ν•˜κ±°λ‚˜ ν•„μš”ν•œ 정보λ₯Ό μΆ”μΆœν•˜λŠ” μž‘μ—…μ„ 더 효율적으둜 ν•  수 μžˆμŠ΅λ‹ˆλ‹€.



-->