일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- docker
- bash
- TypeScript
- nginx
- security
- VUE
- Clone
- condition
- C#
- loop
- AI
- property
- var
- JavaScript
- npm
- vue.js
- git
- scss
- machine learning
- type
- leetcode
- vuetify
- generic
- C++
- Python
- 보안
- webpack
- BOJ
- dotenv
- 앙상블
- Today
- Total
ice rabbit programming
정규표현식 간단 정리 본문
개발을 할 때 종종 정규표현식을 사용할 일이 있습니다. 특정 패턴의 버전을 입력해야 하는 유효성 검사를 하거나, string으로 넘어온 인자들을 파싱할 때 등 여러 경우에 사용합니다.
최근에는 언어에서 지원해주는 라이브러리들도 많고, 자주 쓰이는 패턴의 경우에는 검색하면 금방 나오기도 합니다.
하지만 코딩과 마찬가지로 긁어서 가져다 쓰는 것만이 아니라 이해하고 활용하고, 수정하고 나아가서는 직접 만들 줄도 알아야 한다고 생각합니다.
아래는 근래에 정규표현식 관련해서 책을 읽으면서 나름대로 정리한 내용입니다.(근래라고는 썼지만 몇 달 되긴 했네요.)
https://regexr.com/ 와 같은 곳에서 직접 만들고 테스트해볼 수도 있습니다.
(혼자 정리용으로 필기한 글이라 최대한 가독성 좋게 수정하기는 했습니다만 잘 읽히지 않는 부분이 있을 수도 있습니다.)
정규표현식(Regular Expression, regex) : 일치하는 텍스트를 찾거나(검색), 찾은 텍스트를 치환하는(치환) 도구.
가장 쉽게는 문자를 그대로 찾을 수 있다.
This my car. 에서 my 를 구문으로 찾으면 my가 검색된다. 여러 일치된 결과물을 받을 수도 있다. 대소문자 구분은 하는 것이 디폴트이지만 옵션으로 구분하지 않을 수도 있다.
모든 문자에 대응하는 마침표
와일드카드로 마침표(.)가 있다. 예를 들어 c.t 로 검색하면 cat, cot 등이 모두 검색된다. 마침표 한 개는 한 개의 아무 문자를 의미한다. Sales.. 로 검색하면 Sales.hi, sales.hello 등이 모두 검색된다.
만약 진짜 마침표를 찾고 싶다면 escape문자로 \. 를 써주면 된다. 이것을 정규표현식에서는(다른 곳에서도 많이 쓰는 표현이지만) 메타 문자라고 한다. 역슬래시 자체는 \\ 이다.
여러 문자의 집합
모든 문자가 아니라 일부 문자만을 넣고 싶다면, 대괄호([])로 일치하는 문자들을 넣을 수 있다. 특정 구역에서 대소문자를 구분하지 않을 때 많이 사용한다.
예를들어 [Rr]rg[Ee]X와 같은 식이다.
대괄호에 넣은 문자가 많을 경우에는 다 적기가 번거로우므로, 하이픈(-)으로 범위를 지정할 수 있다.
예를 들어 [ns]a[0-9]\.xls와 같은 식이다. A-Z, a-z, A-F, A-z 등으로 활용 가능하다. 여기서 하이픈은 대괄호 내에서만 유효한 메타 문자이므로, 대괄호 안이 아닌 이상 \를 붙여줄 필요가 없다.
[A-Za-z0-9]는 모든 영문자, 숫자를 의미한다.
반면에 몇 개만 빼고 모두 찾아야할 경우에는 제외하는 것이 빠르다. 그럴 때에는 캐럿 문자(^) 를 사용한다. 다음과 같이 사용하면 숫자를 제외할 수 있다.
[ns]a[^0-9]\.xls이다.
메타 문자
상술했듯이 역슬래시(\)를 활용한 escape 문자를 이용하여, 대괄호나 마침표 등을 검색할 수 있다.
공백 문자는 [\b] – 백스페이스, \f – 페이지 넘김, \n – 개행, \t – 탭 등으로 검색할 수 있다. 덧붙여 마침표(.)는 거의 모든 문자를 탐색하지만 대부분의 엔진에서 공백 문자는 제외된다.
추가적으로 윈도우에서는 \r\n이 줄의 끝을 나타내고, 유닉스/리눅스 계열에서는 \n이 줄의 끝을 나타낸다.
문자 집합, 숫자 집합 등은 굉장히 자주 쓰이는 조합이기 때문에, 편의를 이유로 메타 문자로 해당 클래스들을 만들어 놓는다.
\d – 숫자 하나, \D – 숫자를 제외한 문자 하나, \w – 대소문 영문자, 숫자, 밑줄, \W – 대소문 영문자 및 숫자 및 밑줄을 제외한 문자, \s – 모든 공백 문자, \S 공백 문자가 아닌 문자
진수도 메타 문자로 쓸 수 있다. 16진수는 \x로 표시, 8진수는 \0으로 표기한다.
POSIX 문자 클래스로도 줄여 쓰기를 제공하는데, [:alpha:]와 같이 대괄호와 콜론 사이에 단어가 들어간다. 단, 이는 자바스크립트에서는 지원하지 않는다. POSIX는 자체로 대괄호를 문법에 포함하므로, 집합을 나타내는 대괄호와 함께 [[:alpha:]]와 같이 사용되는 것이 일반적이다.
반복 찾기
이전까지는 한 글자에 대한 찾기였으나 둘 이상의 글자를 찾는 것이 필요하다. 그럴 때 더하기(+)를 뒤에 붙이면 하나 이상의 문자와 일치하는지를 찾는다(ex. a+이면 연속되는 a를 모두 찾는다).
더하기는 최소한 하나의 일치하는 문자가 존재해야 하지만, 별표(*)는 일치하는 문자가 존재하거나 아예 없거나이다(불일치하는 경우만 걸러진다).
더해서 물음표(?)는 더하기와 별표의 중간인데, 딱 한 문자가 일치하거나 문자가 존재하지 않거나이다.
중괄호({})를 사용해서 바로 앞 문자의 구간을 지정해 줄 수도 있다. 하나만 적으면 정확한 개수, 두 개를 적으면 개수의 범위이다. 쉼표를 적으면 최소한의 의미가 된다.
Ex) \d{1,2}\d{3}\d{3,}
1개 이상 2개 이하의 숫자, 3개의 숫자, 최소한 3개의 숫자.
과도하게 일치하는 것을 방지하기 위해 lazy 수량자를 이용한다.
*는 *?, +는 +?, {n,}는 {n,}?이다. 일치하는 최소한의 문자만을 찾는다.
위치 찾기
위치 찾기는 문자열 내에서 반드시 일치해야 하는 위치를 지정할 때 사용한다. Cat을 검색했는데 cat과 scatter가 모두 검색되는 등의 문제를 방지하기 위함.
위 문제는 앞뒤로 단어의 끝을 나타내는 \b를 삽입하여 해결할 수 있다(\bcat\b). \b는 단어가 아니라 위치를 가리키기 때문에, 찾은 문자열의 길이는 3이 된다.
단어 경계를 반대로 제외시키고 싶을 때에는 \B를 사용한다. 메타 문자에서 대소문자는 주로 반대의 역할을 가진다.
캐럿(^) 문자는 문자열의 시작을 의미한다. 즉, 반드시 1째 줄의 시작이어야 하는 경우에 사용할 수 있다. [^로 쓰일 경우에는 부정을 의미하지만, 대괄호 바깥에서는 문자열의 시작으로 쓰인다.
$ 문자는 반대로 문자열의 끝이다. 즉, 마지막 줄의 끝이어야 하는 경우에 사용한다.
?m을 정규표현식 맨 앞에 붙여 다중 행을 지원한다면, ^와 $는 줄바꿈 문자를 문자열의 시작/끝으로 같이 인식하게 된다.
하위 표현식 사용하기
반복 메타 문자는 자신의 바로 앞 한 글자에 대해서만 작동한다. 예를 들어 {2,}의 경우에는 가 반복되는 것을 찾고 싶었으나 ;만의 반복을 찾게 된다.
이 때 하위 표현식을 사용하면 된다. 소괄호로 묶으면 된다. ( ){2,}
괄호 안에는 정규 표현식이 들어갈 수도 있다. (\d{1,3}\.){3}과 같은 식. 반복하려는 패턴의 영역을 정의하거나 OR 조건을 적절하게 정의할 때 주로 사용된다.
물론 응용하여 중첩(nested)도 가능하다. 괄호 안의 괄호
역참조 사용하기
역참조는 패턴 중 하나로, 앞서 일치한 부분을 다시 가리키는 패턴이다. 하위표현식의 맨 끝에 \1을 붙이면 앞에 일치했던 패턴과 일치하는지를 찾게 된다.
Ex) [ ]+(\w+)[ ]+\1 : 앞뒤로 공백이 하나 이상이며, 문자가 하나 이상 등장하는 하위 표현식이 등장한다. 마지막의 \1는 앞서 일치한 하위 표현식이 또 있는지를 확인한다.
\1은 처음 사용한 하위 표현식과 일치하는지를 확인한다. \2는 두 번째, \3는 세 번째…와 같은 사용이 가능하다.
역참조 문법은 정규 표현식 구현에 따라서 상이한 경우가 많으므로, 해당 스택에서의 용법을 확인하고 사용할 것.
l 치환 작업을 할 때에는 정규 표현식이 두 개 필요하다. 검색할 때 사용하는 표현식, 치환할 때 사용하는 표현식. 아래 예제를 보자.
이메일을 검색하여 href 형태로 바꿀 때 역참조로 간단하게 할 수 있다.
검색 패턴 : (\w+[\w\.]*@[\w\.]+\.\w+)
치환 패턴 : <A HREF=mailto:$1>$1</A>
위 치환 패턴에서 $1이 역참조를 담당하고 있다.
전후방탐색
문자열 자체가 아닌, 문자열의 위치를 찾고 싶은 경우에 탐색(look around)를 사용한다. 예를 들어, <title></title> 태그 사이에 있는 문자만을 결과로 조회하고 싶은 경우.
전방 탐색은 일치 영역을 발견해도 그 값을 반환하지 않는 패턴이다. 실제로는 하위 표현식이다. ?=로 시작하고 = 다음에 일치할 텍스트가 온다.
Ex) .+(?=:) 와 같이 작성을 하면, 콜론이 등장하기 전까지의 텍스트가 반환된다. 만일 전방 탐색을 빼면 콜론까지 포함한 값이 반환된다.
후방 탐색은 뒤쪽을 탐색하는데, ?<=이다. 전방 탐색과 사용법이 같고, 일치하는 뒷부분을 반환한다.
Ex) (?<=/$)[0-9.]+
맨 첫 태그 내 텍스트를 가져오는 경우와 같이, 전후방탐색을 함께 사용할 수도 있다.
위에 적은 전후방탐색의 반대 표현인 부정형 전후방탐색도 있는데 = 대신에 !를 사용하면 된다.
?! 와 ?<!
조건 달기
조건을 사용할 때에는 ?를 사용하는데, 이전에 썼던 것들 중 역참조, 전후방탐색을 사용하여 조건 처리가 가능하다.
역참조 조건은 (?(역참조 표현)true)로 쓸 수 있다. (?(역참조 표현)true|false)로 하면 else문과 같이 동작한다. 즉, ?로 시작한 역참조 표현이 존재하면 true 위치에 있는 표현식이, 없으면 false 위치의 표현식이 동작한다.
전후방탐색은 역참조와 동일하게 사용하면 된다.
'Development' 카테고리의 다른 글
[flutter] Unable to find bundled Java version 오류가 발생할 경우 (0) | 2023.12.27 |
---|---|
[Dev] 리팩토링 필요성에 관한 간략한 고찰 (0) | 2021.01.31 |
[VS] Visual Studio에서 열린 탭이 초기화될 때 (3) | 2020.05.21 |