korean-regex

Regex for Korean


Keywords
regex, korean, linguistics, regular-expression
License
MIT
Install
pip install korean-regex==0.2.0

Documentation

korean-regex: Regex for Korean

μ†Œκ°œ

korean-regexλŠ” ν•œκ΅­μ–΄(ν•œκΈ€)을 λΆ„μ„ν•˜κΈ° μœ„ν•΄ regex(μ •κ·œν‘œν˜„μ‹)에 문법을 μΆ”κ°€ν•œ νŒ¨ν‚€μ§€μž…λ‹ˆλ‹€. korean-regexλ‘œλŠ” ν•œκΈ€κ³Ό κ΄€λ ¨ν•œ λ§Žμ€ μΆ”κ°€ κΈ°λŠ₯을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

Rust 바인딩을 μ‚¬μš©ν•˜μ—¬ 맀우 μ„±λŠ₯이 μ’‹μŠ΅λ‹ˆλ‹€.

import kre
regex = kre.compile(r'\b[^ ]+(?=[::^0]).\b')
print(regex.findall('ko_reλŠ” ν•œκ΅­μ–΄(ν•œκΈ€)을 λΆ„μ„ν•˜κΈ° μœ„ν•΄ regex(μ •κ·œν‘œν˜„μ‹)에 문법을 μΆ”κ°€ν•œ νŒ¨ν‚€μ§€μž…λ‹ˆλ‹€. ko_reλ‘œλŠ” ν•œκΈ€κ³Ό κ΄€λ ¨ν•œ λ§Žμ€ μΆ”κ°€ κΈ°λŠ₯을 μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.')) # ['ko_reλŠ”', 'ν•œκ΅­μ–΄(ν•œκΈ€)을', 'regex(μ •κ·œν‘œν˜„μ‹', '문법을', 'μΆ”κ°€ν•œ', 'ko_reλ‘œλŠ”', 'κ΄€λ ¨ν•œ', 'λ§Žμ€', 'κΈ°λŠ₯을', 'μ‚¬μš©ν• ']

μ„€μΉ˜

korean-regexλŠ” pipλ₯Ό 톡해 μ„€μΉ˜ν•˜μ‹€ 수 μžˆμŠ΅λ‹ˆλ‹€. kreλ₯Ό μ„€μΉ˜ν•˜λŠ” 것이 μ•„λ‹Œ korean-regexλ₯Ό μ„€μΉ˜ν•΄μ•Ό ν•œλ‹€λŠ” 점에 μ£Όμ˜ν•˜μ„Έμš”.

pip install -U korean-regex

상세

이 ν”„λ‘œμ νŠΈλŠ” 동λͺ…μ˜ 러슀트 ν”„λ‘œμ νŠΈλ₯Ό 파이썬으둜 λ°”μΈλ”©ν•œ κ²ƒμž…λ‹ˆλ‹€. 기본적인 μž‘λ™ 방식은 μ™„μ „νžˆ κ°™μœΌλ‹ˆ 쑰금 더 μžμ„Έν•œ μ„€λͺ…이 ν•„μš”ν•˜λ‹€λ©΄ 이 링크λ₯Ό μ°Έκ³ ν•˜μ„Έμš”.

기본적으둜 korean-regexλŠ” bracket expressionμ—μ„œ νŠΉμ •ν•œ 쑰건을 λ°œμƒμ‹œμΌ°μ„ λ•Œ μž‘λ™ν•˜λŠ” 좔가적인 κΈ°λŠ₯을 κ°€λ―Έν•œ κ²ƒμž…λ‹ˆλ‹€. ν•΄λ‹Ή 쑰건을 μ œμ™Έν•œ λ‚˜λ¨Έμ§€ μƒν™©μ—μ„œλŠ” 파이썬의 κΈ°λ³Έ re λΌμ΄λΈŒλŸ¬λ¦¬μ™€ λ™μž‘μ΄ μ™„μ „νžˆ κ°™μŠ΅λ‹ˆλ‹€.

μš°μ„  korean-regexλ₯Ό 뢈러였렀면 kre.compile()을 μ‚¬μš©ν•©λ‹ˆλ‹€. compile외에도 kre.subλ‚˜ kre.search, kre.match와 같이 λ°”λ‘œ μ‚¬μš©ν•˜λŠ” 것도 κ°€λŠ₯ν•©λ‹ˆλ‹€.

korean-regexμ—μ„œ μ²˜λ¦¬λ˜λŠ” ꡬ문은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€: [μ΄ˆμ„±:쀑성](가와 같은 쒅성이 μ—†λŠ” κΈ€μžμ˜ 경우) λ˜λŠ” [μ΄ˆμ„±:쀑성:μ’…μ„±], λ˜ν•œ μ΄λŠ” regex의 bracket expression처럼 κΈ€μžλ₯Ό μ£½ μ΄μ–΄μ„œ μ“°κ±°λ‚˜ -을 μ²˜λ¦¬ν•˜λŠ” κ²ƒμœΌλ‘œ μ—¬λŸ¬ μŒμ†Œ(μ†Œλ¦¬μ˜ μ΅œμ†Œ λ‹¨μœ„λ‘œ, 자음과 λͺ¨μŒμ„ μ˜λ―Έν•©λ‹ˆλ‹€.)λ₯Ό μ„ νƒν•©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄ [γ„±γ„΄:ㅏ]λŠ” regexκ΅¬λ¬Έμ—μ„œ [κ°€λ‚˜]λ₯Ό μ˜λ―Έν•˜κ³ , [γ„Ήγ…Ž:γ…—:γ„Άγ…ˆ]은 [λ‘’λ‘²ν˜Ύν™Ž]을 μ˜λ―Έν•©λ‹ˆλ‹€. λ˜ν•œ [γ„±-γ„Ή:ㅏ]λŠ” [κ°€κΉŒλ‚˜λ‹€λ”°λΌ]λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€([κ°€λ‚˜λ‹€λΌ]κ°€ μ•„λ‹˜μ— μ£Όμ˜ν•˜μ„Έμš”!).

# μ˜ˆμ‹œ μ½”λ“œ
import kre
some_regex = kre.compile('[γ„±γ„΄:ㅏㅓㅣ:γ„Άγ„·γ„Ήγ…Š]')
print(some_regex) # re.compile('[κ°†κ°‡κ°ˆκ°—κ±Άκ±·κ±Έκ²‡κΈΆκΈ·κΈΈκΉ‡λ‚žλ‚Ÿλ‚ λ‚―λ„Žλ„λ„λ„Ÿλ‹Žλ‹λ‹λ‹Ÿ]')
print(some_regex.findall('길을 κ±·λŠ” μ‚¬λžŒμ„ λ³΄μ•˜λ‹€. κ·ΈλŠ” λ‚  λ³Ό 낯이 μ—†μ–΄μ„œ 멀리멀리 떠났닀.')) # ['κΈΈ', 'κ±·', 'λ‚ ', 'λ‚―']

λ˜ν•œ regexꡬ문처럼 ^도 μ§€μ›ν•©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ [^γ„·γ„Ήγ…‰γ…Ž:ㅏ]λŠ” [κ°€κΉŒλ‚˜λ”°λ§ˆλ°”λΉ μ‚¬μ‹Έμ•„μžμ°¨μΉ΄νƒ€νŒŒ](ㅏ μ‘°ν•© 쀑 λ‹€,라,짜,ν•˜ μ—†μŒ.)μž…λ‹ˆλ‹€.

λ§Œμ•½ ν•΄λ‹Ή μžλ¦¬μ— λͺ¨λ“  ꡬ문을 μΌμΉ˜μ‹œν‚€κ³  μ‹Άλ‹€λ©΄ ν•΄λ‹Ή 자리λ₯Ό λΉ„μ›Œλ†“μœΌλ©΄ λ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ [:ㅏ]λŠ” κ°€λŠ₯ν•œ λͺ¨λ“  ㅏ 쑰합을 μ˜λ―Έν•˜κ³ , [:γ…—:γ„΄]은 [κ³€κΌ°λ…Όλˆλ˜”...혼]을 μ˜λ―Έν•©λ‹ˆλ‹€.

κ³ κΈ‰

μ‘°ν•©μ˜ μ‚¬μš©

λœμ†Œλ¦¬λ₯Ό μ œμ™Έν•œ μ‘°ν•©ν˜• μŒμ†ŒλŠ” κ΄„ν˜Έλ₯Ό μ΄μš©ν•΄μ„œ ν‘œν˜„ν•  수 μžˆμŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ γ…šλŠ” (γ…—γ…£)와 μ™„μ „νžˆ 같은 ꡬ문이고, ㄢ은 (γ„΄γ…Ž)κ³Ό μ™„μ „νžˆ κ°™μŠ΅λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ [:γ…žγ…’:γ„Άγ„Ό]은 [:(γ…œγ…”)γ…’:γ„Ά(γ„Ήγ…‚)]κ³Ό κ°™μŠ΅λ‹ˆλ‹€.

0의 μ‚¬μš©

0은 ν•΄λ‹Ή μžλ¦¬μ— μŒμ†Œκ°€ μ—†λ‹€λŠ” μ˜λ―Έμž…λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ [γ„±:ㅏ:0γ„΄γ…Ž]은 [κ°€κ°„κ°›]와 κ°™μŠ΅λ‹ˆλ‹€. μ΄ˆμ„±κ³Ό μ€‘μ„±μ—λŠ” κΈ°λ³Έμ μœΌλ‘œλŠ” 0을 μ‚¬μš©ν•˜λŠ” 것이 κΈˆμ§€λ˜μ§€λ§Œ νŠΉλ³„ν•œ 경우, ν•œ μŒμ†Œλ₯Ό λ‚˜νƒ€λ‚΄κ³  싢을 λ•Œ, μ‚¬μš©λ©λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ [0:ㅏ-γ…œ] ν˜Ήμ€ [0:ㅏ-γ…œ:0]은 [γ…γ…γ…‘γ…’γ…“γ…”γ…•γ…–γ…—γ…˜γ…™γ…šγ…›γ…œ]λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. λ˜ν•œ [γ„±-γ„Ή:0] λ˜λŠ” [γ„±-γ„Ή:0:0]은 [γ„±γ„²γ„΄γ„·γ„Έγ„Ή]λ₯Ό μ˜λ―Έν•©λ‹ˆλ‹€. ν•˜μ§€λ§Œ μ΄ˆμ„±κ³Ό 쀑성에 0이 λ“€μ–΄κ°€λŠ” κ²½μš°λŠ” λͺ‡ 가지 μ œμ•½μ΄ μžˆλŠ”λ°μš”, μš°μ„  0이 λ“€μ–΄κ°€λ©΄ κ·Έ μžλ¦¬μ—λŠ” 0 외에 λ‹€λ₯Έ μŒμ†Œλ₯Ό μž‘μ„±ν•  수 μ—†μŠ΅λ‹ˆλ‹€. λ‹€μŒμ€ λͺ‡ 가지 쑰합은 0을 μ‚¬μš©ν•  수 μ—†λ‹€λŠ” κ²ƒμž…λ‹ˆλ‹€. 예λ₯Ό λ“€μ–΄ [γ„±:0:γ…Ž]을 생각해 λ΄…μ‹œλ‹€. 이런 ν•œκΈ€μ€ 곰곰히 생각해도 μ‚¬μš©ν•  수 μžˆλŠ” ν˜•νƒœλŠ” μ•„λ‹™λ‹ˆλ‹€. 이것 뿐만 μ•„λ‹ˆλΌ [0:ㅏ:γ…Ž]λ‚˜ [0:0:0]도 κΈˆμ§€λ©λ‹ˆλ‹€.

μ •κ·œ 음운 μ„ ν–‰ 자λͺ¨μˆœ

regular_first 자λͺ¨μˆœ('μ •κ·œ 음운 μ„ ν–‰ 자λͺ¨μˆœ' μ΄ν•˜ 'μ„ ν–‰ 자λͺ¨μˆœ')은 λœμ†Œλ¦¬λ‚˜ 자음ꡰ, ν•©μš©μžλ“€μ΄ λ’€λ‘œ 보내진 μˆœμ„œμž…λ‹ˆλ‹€.

κΈ°λ³Έ μˆœμ„œ(μœ λ‹ˆμ½”λ“œ μˆœμ„œ λ˜λŠ” μ‚¬μ „μˆœ)은 λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

  • μ΄ˆμ„±: γ„±γ„²γ„΄γ„·γ„Έγ„Ήγ…γ…‚γ…ƒγ……γ…†γ…‡γ…ˆγ…‰γ…Šγ…‹γ…Œγ…γ…Ž
  • 쀑성: γ…γ…γ…‘γ…’γ…“γ…”γ…•γ…–γ…—γ…˜γ…™γ…šγ…›γ…œγ…γ…žγ…Ÿγ… γ…‘γ…’γ…£
  • μ’…μ„±: γ„±γ„²γ„³γ„΄γ„΅γ„Άγ„·γ„Ήγ„Ίγ„»γ„Όγ„½γ„Ύγ„Ώγ…€γ…γ…‚γ…„γ……γ…†γ…‡γ…ˆγ…Šγ…‹γ…Œγ…γ…Ž

ν•˜μ§€λ§Œ μ„ ν–‰ 자λͺ¨μˆœμ€ λ‹€μŒκ³Ό κ°™μŠ΅λ‹ˆλ‹€:

  • μ΄ˆμ„±: γ„±γ„΄γ„·γ„Ήγ…γ…‚γ……γ…‡γ…ˆγ…Šγ…‹γ…Œγ…γ…Žγ„²γ„Έγ…ƒγ…†γ…‰
  • 쀑성: γ…γ…‘γ…“γ…•γ…—γ…›γ…œγ… γ…‘γ…£γ…γ…’γ…”γ…–γ…˜γ…™γ…šγ…γ…žγ…Ÿγ…’
  • μ’…μ„±: γ„±γ„΄γ„·γ„Ήγ…γ…‚γ……γ…‡γ…ˆγ…Šγ…‹γ…Œγ…γ…Žγ„²γ„³γ„΅γ„Άγ„Ίγ„»γ„Όγ„½γ„Ύγ„Ώγ…€γ…„γ…†

이 μˆœμ„œλŠ” -λ₯Ό 톡해 값에 μ ‘κ·Όν•  λ•Œ μ‚¬μš©λ˜μ§€λ§Œ, 정렬은 일반적인 μœ λ‹ˆμ½”λ“œ μˆœμ„œ(사전 μˆœμ„œ)λŒ€λ‘œ μ •λ ¬λ©λ‹ˆλ‹€.

예λ₯Ό λ“€μ–΄ [γ„±-γ…Ž:0:0]은 κΈ°λ³Έ μˆœμ„œμ—μ„œλŠ” λͺ¨λ“  μ΄ˆμ„±μ„ ν¬ν•¨ν•˜λŠ” [γ„±γ„²γ„΄γ„·γ„Έγ„Ήγ…γ…‚γ…ƒγ……γ…†γ…‡γ…ˆγ…‰γ…Šγ…‹γ…Œγ…γ…Ž]μ΄μ§€λ§Œ, μ„ ν–‰ 자λͺ¨μˆœμ—μ„œλŠ” [γ„±γ„΄γ„·γ„Ήγ…γ…‚γ……γ…‡γ…ˆγ…Šγ…‹γ…Œγ…γ…Ž]μž…λ‹ˆλ‹€.

λ‹€μŒκ³Ό 같은 λ°©μ‹μœΌλ‘œ μ„ ν–‰ 자λͺ¨μˆœμ„ μ‚¬μš©ν•  수 μžˆμŠ΅λ‹ˆλ‹€.

import kre

kre.compile("[γ„±-γ…Ž:ㅏ]", order="regular_first") # μ„ ν–‰ 자λͺ¨μˆœ
kre.compile("[γ„±-γ…Ž:ㅏ]", order="default") # κΈ°λ³Έκ°’(μ‚¬μ „μˆœ)

μ •κ·œν‘œν˜„μ‹ ν”Œλž˜κ·Έκ°€ 더 λ¨Όμ € 였기 λ•Œλ¬Έμ— μ£Όμ˜ν•΄μ•Ό ν•©λ‹ˆλ‹€.

import kre

kre.compile("[γ„±-γ…Ž:ㅏ]", "regular_first") # XXX 였λ₯˜! μ •κ·œν‘œν˜„μ‹ flag둜 처리됨
kre.compile("[γ„±-γ…Ž:ㅏ]", order="default") # μ˜¬λ°”λ₯Έ μ‚¬μš©

release note

  • 0.2.0: order νŒŒλΌλ―Έν„° μΆ”κ°€
  • 0.1.0: 러슀트 λ°”μΈλ”©μœΌλ‘œ μ™„μ „νžˆ μ²˜μŒλΆ€ν„° μž¬μ œμž‘, κΈ°μ‘΄ 버전과 μ™„μ „νžˆ 닀름
  • 0.0.5: make_korean μΆ”κ°€, 이름 λ³€κ²½, νƒ€μž… μΆ”κ°€, λ¦¬νŒ©ν† λ§, 검사 μΆ”κ°€
  • 0.0.4: readme 보강, λ¦¬νŒ©ν† λ§
  • 0.0.3(첫 μ•ˆμ •ν™” 버전): μ‹œμž‘