4 releases (2 breaking)

0.3.0 May 15, 2024
0.2.1 Feb 1, 2024
0.2.0 Feb 1, 2024
0.1.0 Feb 1, 2024

#959 in Text processing

MIT license

44KB
656 lines

korean-regex

한글은 초성, 중성, 종성의 조합이기에 각각을 분리해 분석하거나 사용하는 것이 때때로 유용합니다.

korean-regex는 한글을 초성, 중성, 종성의 조합으로 사용할 수 있도록 합니다.

자세한 설명은 문서를 참고하세요.

use korean_regex::*;

let order = Order::Default;
// 마지막 음절이 받침이 없는 모든 음절 캡쳐
let pattern = compile(r"[::]*[:]\b", &order).unwrap();
let result: Vec<_> = pattern
    .captures_iter("한글은 초성, 중성, 종성의 조합이기에 각각을 분리해 분석하거나 사용하는 것이 때때로 유용합니다.")
    .map(|captures| captures[0].to_string())
    .collect();
assert_eq!(vec!["종성의", "조합이기에", "분리해", "분석하거나", "것이", "때때로", "유용합니다"], result)

lib.rs:

korean-regex

한글은 초성, 중성, 종성의 조합이기에 각각을 분리해 분석하거나 사용하는 것이 때때로 유용합니다.

korean-regex는 한글을 초성, 중성, 종성의 조합으로 사용할 수 있도록 합니다.

Syntax

기본적으로 korean-regex는 한 글자 OR 문법의 확장입니다. 정규표현식의 다른 문법은 건드리지 않습니다.

우선 초성, 중성, 종성은 각각 []로 둘러싸인 뒤 :으로 분리됩니다. 예를 들어 아래의 예시처럼 [::]일 경우 초성에 , 중성에 , 종성에 이 각각 들어가 이 됩니다.

use korean_regex::*;

let order = Order::Default;
assert_eq!("[각]", compile("[ㄱ:ㅏ:ㄱ]", order).unwrap().to_string());

한 파트에 두 개 이상의 문자를 적으면 각 가능한 경우의 수로 변환됩니다. 예를 들어 아래처럼 [ㄱㄴ:ㅏㅣ:]일 경우 모든 경우의 수인 간긴난닌로 대체됩니다.

use korean_regex::*;

let order = Order::Default;
assert_eq!("[간긴난닌]", compile("[ㄱㄴ:ㅏㅣ:ㄴ]", order).unwrap().to_string());

만약 해당 칸은 비워놓는다면 해당 자리는 어떤 것이든 받아들이겠다는 의미입니다. 예를 들어 [::]은 '종성이 인 모든 음소'를 의미합니다.

use korean_regex::*;

let order = Order::Default;
assert_eq!("[갛갷걓걯...흏흫힇힣]", compile("[::ㅎ]", order).unwrap().to_string());

-을 통해 연속되는 음소를 대체할 수 있습니다.

이때 기본적으로 ㄱㄴㄷㄹ...아닌 ㄱㄲㄴㄷㄸㄹ...와 같은 사전순으로 match된다는 점을 주의해 주세요. 이는 중성과 종성도 동일합니다.

use korean_regex::*;

let order = Order::Default;
assert_eq!("[간깐난단딴란]", compile("[ㄱ-ㄹ:ㅏ:ㄴ]", order).unwrap().to_string());
assert_eq!("[간갠갼걘건겐견곈곤관괜괸굔군권궨귄균근긘긴]", compile("[ㄱ:ㅏ-ㅣ:ㄴ]", order).unwrap().to_string());
assert_eq!("[간-갈]", compile("[ㄱ:ㅏ:ㄴ-ㄹ]", order).unwrap().to_string());

0은 해당 자리에 음소가 없다는 것을 의미합니다. 기본적으로 종성에 사용됩니다.

use korean_regex::*;

let order = Order::Default;
assert_eq!("[가각간나낙난다닥단]", compile("[ㄱㄴㄷ:ㅏ:0ㄱㄴ]", order).unwrap().to_string());

하지만 특수하게 [*:0:0]이나 [0:*:0]과 같은 형태도 사용될 수 있습니다.

use korean_regex::*;

let order = Order::Default;
assert_eq!("[ㄱㄲㄴㄷㄸㄹ]", compile("[ㄱ-ㄹ:0:0]", order).unwrap().to_string());
assert_eq!("[ㅏㅐㅑㅒㅓㅔㅕㅖㅗㅘㅙㅚㅛㅜㅝㅞㅟㅠㅡㅢㅣ]", compile("[0:ㅏ-ㅣ:0]", order).unwrap().to_string());

^을 이용하면 해당 음소에 match하고 싶은 문자 대신 match하기 싫은 문자를 지정할 수 있습니다. 예를 들어 초성이 이고 중성이 이면서 받침이 이 아닌 모든 음소는 [::^]로 표현할 수 있습니다.

use korean_regex::*;

let order = Order::Default;
assert_eq!("[가-갇갉-갛]", compile("[ㄱ:ㅏ:^ㄹ]", order).unwrap().to_string());

만약 종성이 없는 문자를 match하고 싶다면 [*:*:0] 대신 [*:*] 문법을 사용할 수도 있습니다. 예를 들어 [ㄱㄴㄷ:ㅏㅣ:0][ㄱㄴㄷ:ㅏㅣ]로 대체될 수 있습니다.

use korean_regex::*;

let order = Order::Default;
assert_eq!("[가기나니다디]", compile("[ㄱㄴㄷ:ㅏㅣ:0]", order).unwrap().to_string());
assert_eq!("[가기나니다디]", compile("[ㄱㄴㄷ:ㅏㅣ]", order).unwrap().to_string());

만약 별개로 몇 개의 글자를 match에 추가하고 싶다면 |를 그 뒤에 추가하면 됩니다.

use korean_regex::*;

let order = Order::Default;
assert_eq!("[과구놔누돠두한abc]", compile("[ㄱㄴㄷ:ㅜㅘ|한abc]", order).unwrap().to_string());

한글에는 두 개 이상의 글자가 합쳐서 생성된 문자들이 있습니다. 이나 , 등이 그 예입니다. 만약 글자 입력기가 같은 문자를 입력하는 것을 지원하지 않거나, 미관상의 이유로 코드에서 피하고 싶다면 괄호를 사용해서 문자를 합칠 수 있습니다.

use korean_regex::*;

let order = Order::Default;
assert_eq!("[곿괇궧궯뽟뽧쀇쀏]", compile("[ㄱ(ㅂㅂ):(ㅗㅏ)(ㅜㅔ):(ㄹㅂ)(ㄱㅅ)]", order).unwrap().to_string());

이 고유 문법이 적용되는 범위를 넘어서면 기본 정규 표현식과 같이 섞어 사용할 수 있습니다.

use korean_regex::*;

let order = Order::Default;
let pattern = compile(r"\b([아-잏][^ ]{0,2})\b", order).unwrap();
let input = "저기 양을 잡아먹는 이리 때가 오르막길을 타고 간다!";
let result: Vec<_> = pattern.find_iter(input).map(|m| m.as_str()).collect();
assert_eq!(vec!["양을", "이리"], result);

Example

다른 문법과 합치면 다음과 같이 사용할 수 있습니다.

use korean_regex::*;

let order = Order::Default;
// 초성이 ㄱ이 아니고 그 뒤에 종성이 `ㅇ`인 모든 글자가 오며 그 다음 글자 바운더리 혹은 종성이 없는 문자가 있는 경우
let pattern = compile(r"[^ㄱ::][::ㅇ](\b|[:])", order).unwrap();
let result: Vec<_> = pattern
    .captures_iter("한글은 초성, 중성, 종성의 조합이기에 각각을 분리해 분석하거나 사용하는 것이 때때로 유용합니다.")
    .map(|captures| captures[0].to_string())
    .collect();
assert_eq!(vec!["초성", "중성", "종성의", "사용하"], result)

Hyphen replacing

정규표현식의 [] 문법에는 연속되는 문자를 대체하는 - 문법이 있습니다.

만약 연속되는 문자가 세 개 이상 있다면 korean-regex에서도 -문법이 이용됩니다.

use korean_regex::*;

let order = Order::Default;
assert_eq!("[가-깋라-맇]", compile("[ㄱㄹ::]", order).unwrap().to_string());

Dependencies

~2.2–3MB
~54K SLoC