ν•΄λŠ”μ„  2020. 2. 26. 17:19

02. YYYY-MM-DD

http://www.dafit.me/question/?q=YToyOntzOjEyOiJrZXl3b3JkX3R5cGUiO3M6MzoiYWxsIjtzOjQ6InBhZ2UiO2k6MTt9&bmode=view&idx=2643277&t=board

 

[DF905] Regular Expression (μ •κ·œ ν‘œν˜„μ‹) : 닀핏, λ°μ΄ν„°μ‚¬μ΄μ–ΈμŠ€ μ—°μŠ΅λ¬Έμ œ

πŸ”₯ 문제 μ„€λͺ…μ‹€λ¬΄μ—μ„œ ν•„μˆ˜μ μœΌλ‘œ μ“°μ΄λŠ” μ •κ·œν‘œν˜„μ‹μ˜ 기초λ₯Ό 두 κ°€μ§€ μ‚¬λ‘€λ‘œ μ΅νžŒλ‹€.μžμ—°μ–΄ 처리 κ΄€λ ¨ 직ꡰ의 μ½”λ”© ν…ŒμŠ€νŠΈμ—μ„œλ„ μ •κ·œν‘œν˜„μ‹ λ¬Έμ œλŠ” 자주 λ“±μž₯ν•œλ‹€. πŸ”₯ μΆ”μ²œ λŒ€μƒμžμ—°μ–΄ 처리λ₯Ό κ³΅λΆ€ν•˜κ³ μž ν•˜λŠ” μ‚¬λžŒ.μžμ—°μ–΄ 처리λ₯Ό κ³΅λΆ€ν•˜κ³  μžˆμ§€λ§Œ μ „μ²˜λ¦¬ μ—°μŠ΅μ΄ λΆ€μ‘±ν•œ μ‚¬λžŒ.μ •κ·œν‘œν˜„μ‹λ§Œ λ‚˜μ˜€λ©΄ μžμ‹ μ΄ μ—†λŠ” μ‚¬λžŒ.νŒŒμ΄μ¬μ„ μ΄μš©ν•œ μ •κ·œν‘œν˜„μ‹ μ—°μŠ΅μ„ ν•˜κ³  싢은 μ‚¬λžŒ.πŸ”₯ ν•™μŠ΅ λͺ©ν‘œμ •κ·œ ν‘œν˜„μ‹μœΌλ‘œ λ°μ΄ν„°μ˜ λ‹€μ–‘ν•œ κ·œμΉ™μ„ ν‘œν˜„ν•  수 μžˆλ‹€.데이터λ₯Ό μ •κ·œ ν‘œν˜„μ‹μ„ μ΄μš©ν•΄μ„œ μ „μ²˜λ¦¬

www.dafit.me

 

λ‚ μ§œλ₯Ό μ •κ·œ ν‘œν˜„μ‹μœΌλ‘œ λ‚˜νƒ€λ‚΄λ³΄μž!

 

일단 λ‚΄κ°€ μ§  컴파일 μ½”λ“œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

import re
p = re.compile('((\d{4})|\d{2})?(-|/|.)?(?P<month>[1-9]|0[1-9]|1[0-2])(-|/|.|μ›” )(?P<date>([1-9]|0[1-9]|[1-2][0-9]|3[01]))일?$')

컴파일 μ½”λ“œλ§Œ λ”°λ‘œ λΉΌμ„œ 봐보자.

 

((\d{4})|\d{2})?(-|/|.)?(?P<month>[1-9]|0[1-9]|[10-12])(-|/|.|μ›” )(?P<date>([1-9]|0[1-9]|[1-2][0-9]|3[01]))일?$')

 

ν•œ μ€„λ‘œ λ§Œλ“€λ‹€ λ³΄λ‹ˆκΉŒ 머리가 ν„°μ§ˆ 것 κ°™μ•˜λ‹€... 이 식은 2월은 28μΌκΉŒμ§€λΌλŠ” λͺ…μ‹œκ°€ μ—†λ‹€. μ™œλƒλ©΄ νž˜λ“€μ–΄μ„œ 밖에 쑰건문을 λ”°λ‘œ λ§Œλ“€μ–΄ 쀬기 λ•Œλ¬Έμ΄λ‹€. λ˜ν•œ, μš°μ„  ν…ŒμŠ€νŠΈ μΌ€μ΄μŠ€μ— 맞게 λ§Œλ“€μ–΄ μ‘Œλ‹€. 일단 κ·Έ 쑰건문은 λ‚˜μ€‘μ— 보고, μ§€κΈˆμ€ 이 μ •κ·œ ν‘œν˜„μ‹μ„ λΆ„ν•΄ν•΄ 보자.

 

((\d{4})|\d{2})?
(-|/|.)?
(?P<month>[1-9]|0[1-9]|1[0-2])
(-|/|.|μ›” )
(?P<date>([1-9]|0[1-9]|[1-2][0-9]|3[01]))
일?$

 

λŒ€μΆ© μ΄λ ‡κ²Œ λ‚˜λˆ  λ³Ό 수 μžˆκ² λ‹€.

 

((\d{4})|\d{2})? λŠ” 연도λ₯Ό λ‚˜νƒ€λ‚Έλ‹€. 2019처럼 4자리 μΌμˆ˜λ„, 19처럼 λ‘μžλ¦¬ 일 μˆ˜λ„ μžˆμ–΄μ„œ | κ΅¬λΆ„μžλ₯Ό ν†΅ν•΄μ„œ λ‘˜ 쀑 ν•˜λ‚˜κ°€ λ“€μ–΄μ˜¨λ‹€κ³  ν–ˆκ³ , μ•„μ˜ˆ μž…λ ₯이 없을 μˆ˜λ„ μžˆμ–΄μ„œ ?λ₯Ό 톡해 λ“€μ–΄μ˜¬μˆ˜λ„, λ“€μ–΄μ˜€μ§€ μ•Šμ„ μˆ˜λ„ μžˆλ‹€κ³  λͺ…μ‹œν•΄ μ£Όμ—ˆλ‹€.

 

(-|/|.)? 은 연도와 월을 κ΅¬λΆ„μ§“λŠ” κ΅¬λΆ„μžλ‹€. μ‰½κ²Œ λ§ν•΄μ„œ 2000-01, 2000/01, 2000.01 을 λœ»ν•œλ‹€. 이 μ—­μ‹œ 연도을 μž…λ ₯λ°›μ§€ μ•ŠμœΌλ©΄ ν•„μš”κ°€ μ—†μ–΄μ Έμ„œ ?λ₯Ό μ΄μš©ν•΄ μžˆμ„ μˆ˜λ„ 있고, 없을 μˆ˜λ„ μžˆλ‹€κ³  λͺ…μ‹œν–ˆλ‹€.

 

(?P<month>[1-9]|0[1-9]|1[0-2]) 은 월을 λ‚˜νƒ€λ‚Έλ‹€. ?Pλ₯Ό μ΄μš©ν•΄μ„œ κ·Έλ£Ήν•‘ν•œ 그룹에 monthλΌλŠ” 이름을 μ£Όμ—ˆλ‹€.

월이 ν•œμžλ¦¬μΌ 경우 01μ›”, 1μ›” 두가지 경우의 μˆ˜κ°€ μžˆμ–΄μ„œ κ·Έ 경우의 수λ₯Ό λ”°λ‘œλ”°λ‘œ ν‘œκΈ°ν•΄ μ£Όμ—ˆλ‹€. 또 λ‘μžλ¦¬μΌ κ²½μš°λ„ λ”°λ‘œ λ§Œλ“€μ—ˆλ‹€. λͺ°λžλŠ”λ°, [ ] μ•ˆμ— λ“€μ–΄κ°€λŠ” μˆ«μžλŠ” ν•œμžλ¦¬ 수둜 μ œν•œλœλ‹€... 즉 10, 11, 12월을 ν‘œκΈ° ν•˜κΈ° μœ„ν•΄ [10-12]κ°€ μ•„λ‹ˆλΌ 1[0-2]둜 ν•΄μ•Ό 함을 λœ»ν•œλ‹€. 꼼수 μ•ˆ ν†΅ν•œλ‹€...

 

(-|/|.|μ›” ) 은 μ›” 뒀에 λ‚˜νƒ€λ‚˜λŠ” κ΅¬λΆ„μžλ‹€. 06-01, 06/1, 06.1, 6μ›” 1일 을 λœ»ν•œλ‹€. ν•œκΈ€ 'μ›”'κ³Ό 뒀에 λ‚˜μ˜€λŠ” 숫자 일 사이에 spaceκ°€ 있기 λ•Œλ¬Έμ— κΌ­ μ €κΈ° μ¨μ€„λ•Œμ—λŠ” 'μ›” '이라고 μ¨μ€˜μ•Ό ν•œλ‹€. white space도 λ¬Έμžλ‹€!!!

 

(?P<date>([1-9]|0[1-9]|[1-2][0-9]|3[01])) 은 일을 λ‚˜νƒ€λ‚Έλ‹€. month와 λ§ˆμ°¬κ°€μ§€λ‘œ 그룹에 dateλΌλŠ” 이름을 μ£Όμ—ˆλ‹€.

일 μ—­μ‹œ 1, 01같이 ν•œμžλ¦¬μ˜ 경우 두 κ°€μ§€μ˜ 경우의 μˆ˜κ°€ λ‚˜νƒ€λ‚  수 μžˆμœΌλ―€λ‘œ λ‹€ ν‘œκΈ°ν•΄μ£Όμ—ˆκ³ , 10~29일 κΉŒμ§€λŠ” [1-2][0-9] 둜 ν‘œκΈ°ν–ˆλ‹€. 30일 λŒ€μ˜ 경우 30, 31 λ‘κ°€μ§€μ˜ 경우의 수 밖에 μ—†μ–΄μ„œ 3[01]둜 ν‘œκΈ°ν–ˆλ‹€.

 

일?$ 은 숫자 일 뒀에 λ‚˜μ˜€λŠ” ν•œκΈ€ '일'을 λœ»ν•œλ‹€. 30일 ν• λ•Œ 이 '일'. 그리고 $이 μ€‘μš”ν•œλ°, λ‚ μ§œλ₯Ό μž…λ ₯ 받을 λ•Œ, μ—°λ„λŠ” μž…λ ₯λ°›μ§€ μ•Šμ•„λ„ μ›”, 일은 κΌ­ μž…λ ₯ λ°›λŠ”λ‹€. 그런데, λ§Œμ•½ 연도λ₯Ό μž…λ ₯λ°›μ§€ μ•ŠλŠ”λ‹€λ©΄ μ›”, 일만 μž…λ ₯ λ°›κ²Œ λ˜λŠ”λ° μ—°λ„μ˜ 경우의 μˆ˜μ—λŠ” 연도가 19처럼 λ‘μžλ¦¬λ‘œ μž…λ ₯λ°›λŠ” κ²½μš°λ„ 있기 λ•Œλ¬Έμ—, 잘λͺ» 되면 μ›”λ‘œ λ“€μ–΄κ°€μ•Ό ν•˜λŠ” 정보가 μ—°λ„λ‘œ λ“€μ–΄κ°€κ²Œ 될 μˆ˜λ„ μžˆλ‹€. 이λ₯Ό λ°©μ§€ ν•˜κΈ° μœ„ν•΄ λ§ˆμ§€λ§‰μ΄ κΌ­ '일'μ΄λΌλŠ” 것을 λ‚˜νƒ€λ‚΄κΈ° μœ„ν•΄ $을 μ‚¬μš©ν•΄μ•Ό ν•œλ‹€.

 

전체 μ½”λ“œλŠ” λ‹€μŒκ³Ό κ°™λ‹€.

import re
p = re.compile('((\d{4})|\d{2})?(-|/|.)?(?P<month>[1-9]|0[1-9]|1[0-2])(-|/|.|μ›” )(?P<date>([1-9]|0[1-9]|[1-2][0-9]|3[01]))일?$')

data = ['2019-06-06', '2019/06/06', '2019.06.06', '19.12.06',
        '6/6', '06/13', '06μ›” 3일', '6μ›” 20일', '2019.06.41',
        '2019.13.30', '2000.00.01', '2000.2.31'
]

for i in data:
    m = p.match(i)
    if m and ((1 if (int(m.group("date"))<=28) else 0) if int(m.group("month"))==2 else 1):
        print('REPLACEDATE')
    else:
        print(i)

쀑간에  쑰건문을 μ΄μš©ν•΄μ„œ 2월이 28일이 λ„˜μ–΄κ°€λŠ”μ§€ κ²€μ‚¬ν•˜λ„λ‘ ν–ˆλ‹€. python의 3ν•­ μ—°μ‚°μžλ₯Ό μ΄μš©ν–ˆλ‹€.

 

κ²°κ³ΌλŠ” 잘 λ‚˜μ˜¨λ‹€.


μ •κ·œ ν‘œν˜„μ‹... μž¬λ°ŒλŠ”λ° μ–΄λ ΅λ‹€γ… 

λŒ“κΈ€μˆ˜0