-
[Go] regexp 패키지와 정규표현식 알아보기Golang 2024. 6. 8. 13:08728x90반응형
- 목차
들어가며.
Go 언어에서 regexp 패키지는 정규식(Regular Expressions) 을 통해서 문자열을 처리하고 분석하는 도구입니다.
이번 글에서는 regexp 패키지의 기본 사용법과 실전에서 유용한 예제를 다룹니다.
Golang 의 regexp 란 ?
Go 의 regexp 패키지는 정규식 기반으로 문자열을 매칭, 검색, 대체, 분리하는 기능을 제공합니다.
regexp 패키지의 대표적인 기능은 아래와 같습니다.
- Compile: 정규식을 컴파일하여 Regexp 객체 생성.
- MatchString: 문자열이 정규식에 매칭되는지 확인.
- Find: 정규식에 매칭되는 부분 문자열 반환.
- ReplaceAllString: 정규식에 매칭되는 부분을 다른 문자열로 대체.
- Split: 정규식을 기준으로 문자열 분리.
type Regexp struct.
Regexp 는 Go 의 정규식 객체를 표현하는 구조체로, 정규식 패턴을 컴파일한 결과를 담고 있습니다.
Regexp 구조체의 구성과 설명은 아래와 같습니다.
type Regexp struct { expr string // as passed to Compile prog *syntax.Prog // compiled program onepass *onePassProg // onepass program or nil numSubexp int maxBitStateLen int subexpNames []string prefix string // required prefix in unanchored matches prefixBytes []byte // prefix, as a []byte prefixRune rune // first rune in prefix prefixEnd uint32 // pc for last rune in prefix mpool int // pool for machines matchcap int // size of recorded match lengths prefixComplete bool // prefix is the entire regexp cond syntax.EmptyOp // empty-width conditions required at start of match minInputLen int // minimum length of the input in bytes // This field can be modified by the Longest method, // but it is otherwise read-only. longest bool // whether regexp prefers leftmost-longest match }
Complie, MustCompile, Copy 등과 같은 regexp 패키지의 함수들은 Regexp struct 를 생성합니다.
Compile.
regexp 패키지의 Compile 함수는 아래와 같은 시그니처를 가집니다.
Compile 함수는 정규표현식 문자열을 입력값으로 받으며 Regexp 구조체의 포인터를 반환합니다.
반환되는 Regexp 구조체는 입력값으로 주어진 정규식 패턴을 컴파일한 결과입니다.
func Compile(expr string) (*Regexp, error)
아래와 예시는 1개 이상의 숫자를 캡처하는 Regexp 구조체를 생성합니다.
그리고 Regexp 의 Method 인 MatchString 을 통해서 특정 문자열이 1개 이상의 숫자를 포함하는지 여부를 판단합니다.
("\d+" 정규표현식은 1개 이상의 숫자를 의미합니다. )
package main import ( "fmt" "regexp" ) func main() { pattern := `\d+` re, _ := regexp.Compile(pattern) fmt.Println(re.MatchString("12345")) // true }
위 예시처럼 string "12345" 은 숫자를 포함하는 문자열이기에 "\d+" 패턴을 만족합니다.
MustCompile.
regexp.MustCompile 는 Go 의 표준 라이브러리 regexp 패키지에서 정규식을 컴파일할 때 사용하는 함수 중 하나입니다.
이 함수는 정규식이 유효하지 않은 경우 패닉(panic)을 발생시킨다는 점에서 일반적인 regexp.Compile 과 차이가 있습니다.regexp.Compile 함수는 Regex 구조체와 error 를 함께 반환하여 Caller 함수에 Error Handling 을 책임을 전가합니다.
반면 MustCompile 은 내부적으로 에러 발생 시에 Panic 을 발생하게 되며, 이를 recover 방식으로 Error Handling 이 가능합니다.
MustCompile 함수의 시그니처는 아래와 같습니다.
func MustCompile(str string) *Regexp
아래의 예시는 잘못된 Pattern 으로 MustCompile 사용 시에 발생할 수 있는 panic 과 recover 예시입니다.
"??" 패턴은 정규표현식으로 사용될 수 없습니다.
그 이유는 "?" 0개 이상의 반복을 의미하게 되는데요.
그렇기 때문에 ? 앞에 반드시 특정 문자가 위치해야합니다.
package main import ( "fmt" "regexp" ) func main() { pattern := `??` defer func() { if r := recover(); r != nil { fmt.Println("Recovered from panic:", r) } }() re := regexp.MustCompile(pattern) fmt.Println(re.MatchString("12345")) }
MatchString.
regexp.MatchString 은 Go 의 regexp 패키지에서 제공하는 함수로, 주어진 문자열이 특정 정규식 패턴과 일치하는지 확인할 때 사용됩니다.
이 함수는 문자열이 정규식과 매칭되면 true, 매칭되지 않으면 false를 반환합니다.MatchString 함수의 시그니처는 아래와 같습니다.
func MatchString(pattern string, s string) (matched bool, err error)
MatchString 함수의 사용 예시는 아래와 같습니다.
package main import ( "fmt" "regexp" ) func main() { pattern := `\d{5}` matched, _ := regexp.MatchString(pattern, "12345") fmt.Println("matched: ", matched) // matched: true matched, _ = regexp.MatchString(pattern, "123") fmt.Println("matched: ", matched) // matched: false matched, _ = regexp.MatchString(pattern, "abc12345qwe") fmt.Println("matched: ", matched) // matched: true pattern = "??" _, err := regexp.MatchString(pattern, "abc12345qwe") if err != nil { fmt.Println("matched: ", err.Error()) // matched: error parsing regexp: missing argument to repetition operator: `??` } }
Find.
regexp.Find 는 Go 의 정규식 패키지 regexp 에서 특정 패턴과 매칭되는 첫 번째 문자열을 찾는 함수입니다.
이 함수는 정규식을 사용해 주어진 입력에서 원하는 부분 문자열을 추출할 때 유용합니다.
Find 의 시그니처는 아래와 같습니다.
주목할 점은 입력과 출력값의 데이터 타입이 []byte 슬라이스 타입입니다.
func (re *Regexp) Find(b []byte) []byte
아래는 regexp.Find 의 활용 예시입니다.
regexp.Find 함수는 string 과 []byte 의 변환에 유의해야합니다.
package main import ( "fmt" "regexp" ) func main() { pattern := `\d{5}` var re *regexp.Regexp = regexp.MustCompile(pattern) var text string = "111112222233333" output := re.Find(([]byte)(text)) fmt.Println("find: ", string(output)) // find: 11111 }
FindString.
regexp.Find 함수는 []byte 타입의 입력과 출력값을 취급합니다.
반면, string 타입의 데이터를 다루어야한다면 FindString 함수를 사용할 수 있습니다.
regexp.FindString 함수의 활용 예시는 아래와 같습니다.
package main import ( "fmt" "regexp" ) func main() { pattern := `\d{5}` var re *regexp.Regexp = regexp.MustCompile(pattern) var text string = "111112222233333" output := re.FindString(text) fmt.Println("find: ", output) // find: 11111 }
FindAll.
Find 와 FindString 함수는 문자열에서 Pattern 과 매칭되는 첫번째 부분 문자열이 출력됩니다.
Pattern Matching 되는 모든 부분 문자열을 추출해야한다면 FindAll 함수를 활용해야합니다.
regexp.FindAll 함수의 시그니처는 아래와 같습니다.
아래와 같이 FindAll 함수는 Regexp 구조체의 Method 로 표현됩니다.
func (re *Regexp) FindAll(b []byte, n int) [][]byte
regexp.FindAll 함수의 활용 예시는 아래와 같습니다.
package main import ( "fmt" "regexp" ) func main() { pattern := `\d{5}` var re *regexp.Regexp = regexp.MustCompile(pattern) var text string = "111112222233333" output := re.FindAll(([]byte)(text), 3) for index, subStrBytes := range output { fmt.Printf("find %d: %s \n", index, string(subStrBytes)) } // find 0: 11111 //find 1: 22222 //find 2: 33333 }
FindAll 함수는 2개의 인자를 필요로 합니다.
첫번째 인자는 Pattern 을 탐색할 문자열입니다.
그리고 반드시 첫번째 인자로 사용되는 문자열은 []byte 타입으로 변경되어야 합니다.
FindAll 함수는 반환값으로 [][]byte 를 반환하는데, 이 slice 에서 사용할 Length 값을 두번째 인자로 필요로 합니다.
찾고자하는 Sub String 이 2개인 경우에 아래와 같이 FindAll 의 두번재 인자를 2로 설정하면 됩니다.
이 경우에 총 3개의 부분 문자열이 존재하더라도 2개의 값만을 탐색하게 됩니다.
output := re.FindAll(([]byte)(text), 2) for index, subStrBytes := range output { fmt.Printf("find %d: %s \n", index, string(subStrBytes)) } // find 0: 11111 // find 1: 22222
반응형'Golang' 카테고리의 다른 글
[Golang] time 패키지의 기본적인 사용법 알아보기 ( Now, LoadLocation ) (0) 2024.06.12 [Golang] encoding/json 패키지 알아보기 (0) 2024.06.12 golang package 이해하기 (2) 2023.09.18 golang struct 이해하기 (0) 2023.09.18 golang cobra (0) 2023.01.27