정규 표현식 Regular Expression

백경·2022년 10월 12일
1

정규식

정규 표현식 또는 정규 식
Regular Expression

  • 쉽게, 문자열에서 특정 문자 조합을 찾기 위한 패턴

촘스키 언어학에 따른 형식 언어학 의 표현

  • 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 형식 언어
  • 정규 문법을 대수학적인 성질로 표현

형식 언어학에서는

언어는 자연 언어와 형식 언어로 구분

  • 자연 언어는 영어, 한국어 등 인류가 자연적으로 만든 언어
  • 형식 언어는 특정한 용도를 위해서 만들어낸 언어

형식 언어의 구분

촘스키 문법 분류

  • Type 0 문법 - Unrestricted Grammar; UG
  • Type 1 문법 - Context Sensitive Grammar; CSG
  • Type 2 문법 - Context Free Grammar; CFG
  • Type 3 문법 - Regular Grammar; RG (정규 문법)

형식 언어의 종류

  • Type 0 - recursively enumerable set
  • Type 1 - context-sensitive language
  • Type 2 - context-free language
  • Type 3 - regular language (정규 언어)

정규 표현이란

정규 문법을 대수학적인 성질로 표현한 표현식

정규 표현식은

형식 언어 중 정규 문법의 적용을 받는 정규 언어이다

# 형식 언어
## 형식 언어(形式言語, formal language)란
- 특정한 법칙들에 따라 적절하게 구성된 문자열들의 집합
- 의미의 개념은 포함하지 않는 문자열들의 집합
- 문법 구조만 고려 
- 인공 언어 
- 종류 - 오토마타, 정규 표현식 
- 구성 - 알파벳과 문자열 
정규 문법 
- 촘스키 문법 규칙 Type 3
- Token 구조 표현

웹 프로그래밍은

문자열을 다루는 빈도가 특히 높기 때문에 사용하는게 거의 필수적
예를 들면

  • 위키위키만 해도 DB에 저장된 텍스트에 있는 위키 문법을 엔진에서 해석해서 출력해주는 작업이 필요한데, 위키 문법도 일정한 규칙이 있는 문자열이니만큼 이 작업에서 정규표현식은 반드시 들어간다.

프로그래밍 언어마다 다른 정규식

정규 표현식은 언어마다 문법이 조금씩 다른데 크게 나누면

  • POSIX
    - 표준으로 인정된 정규 표현식
    - Basic, Extended 2가지
  • PCRE
    - Perl 방식으로 POSIX 서 문법을 매우 확장
    - PCRE의 경우 이미 정규표현식이라고 부를 수 없을 정도로 기능이 확장
  • 이외에도 Emacs와 Vim 모두 자체적인 정규표현식을 지원

문법

  • 메타 문자
  • 문자 집합과 특수 문자
  • 하위 표현식
  • 수량자
  • 패턴변경자

메타 문자

다른 언어에서 연산자나 예약어로 쓰이는 문자
앞에 \ 를 붙여서 escape 해주어야 사용할 수 있다

\ ^ $ . | [ ] ( ) * + ? { }

이스케이프 문자

  • \n 개행 문자
  • \t 탭 문자
  • \w 문자
  • \W 문자가 아닌 글자

그 외

  • ^ 문자열의 시작
  • $ 문자열의 종료
  • . 모든 아무 문자 하나 (개행 문자는 비포함인 경우가 많다)
  • | 왼쪽이나 오른쪽 패턴 중 하나 일치

문자 집합과 특수 문자

문자 집합

문자 집합 = 문자 클래스

대괄호 한 쌍으로 정의되는 문장

  • [ ]

문자 집함 전용 메타 문자

  • ^: 해당 집합에 포함된 문자들을 검색에서 제외
  • ~문자와 문자 사이에 있을 경우 해당하는 문자 코드 범위 내의 모든 문자를 포함
    - 역순이 되면 안 된다.
    - 문자로서의 ~ 를 찾고 싶다면 문자 집합의 제일 앞이나 뒷 부분에 위치하여야 한다
    - [a~z], [A~Z]
    - [~a~z], [a~z~]

특수 문자

이스케이프 문자

대문자를 사용하면 해당 문자 집합을 제외하는 ^ 문자와 동일하다

  • \b: 문자와 공백 사이를 의미한다.
  • \c: 제어 문자를 의미한다.
  • \d: 숫자에 해당하는 유니코드에 대응. [0-9]와 달리 아랍 문자, 페르시아 문자 등 다양한 숫자를 포괄한다.
  • \f: 폼 피드
  • \n: 개행 문자
  • \s: 공백 문자
  • \t: 탭 문자
  • \v: 수직 탭
  • \w : 단어. 영문자+숫자+_(밑줄) [0-9a-zA-Z_]
  • \x: 16진수 값
  • \0: 8진수 값

[자주 사용하는 문자 클래스]

  • \d - 숫자와 매치, [0-9]와 동일한 표현식이다.
  • \D - 숫자가 아닌 것과 매치, [^0-9]와 동일한 표현식이다.
  • \s - whitespace 문자와 매치, [ \t\n\r\f\v]와 동일한 표현식이다. 맨 앞의 빈 칸은 공백문자(space)를 의미한다.
  • \S - whitespace 문자가 아닌 것과 매치, [^ \t\n\r\f\v]와 동일한 표현식이다.
  • \w - 문자+숫자(alphanumeric)와 매치, [a-zA-Z0-9_]와 동일한 표현식이다.
  • \W - 문자+숫자(alphanumeric)가 아닌 문자와 매치, [^a-zA-Z0-9_]와 동일한 표현식이다.

하위 표현식

패턴을 소괄호 한 쌍으로 둘러싼다

  • (.), (.+)

수량자

패턴이 반복함을 나타내는 문법
패턴 뒤에 중괄호 또는 메타 문자가 붙는다

  • {n} - 정확히 n 번 반복할떄 일치
  • {n,} - n 번 이상 반복할떄 일치
  • {n,m} - n 번에서 m번 안으로 반복할떄 일치

미리 정의된 반복 횟수를 메타 문자로 지정 가능

  • * : 패턴이 일치하지 않거나 한번 이상 반복할때 일치한다. {0,}과 같다.
  • + : 패턴이 한번 이상 반복할때 일치한다. {1,}과 같다.
  • ? : 패턴이 일치하지 않거나 한번만 반복할때 일치한다. {0,1}과 같다.

탐욕적 수량자: *, +, {n,}
게으른 수량자: *?, +?, {n,}?

패턴변경자

패턴구분자가 끝나면 그 뒤에 쓰는 것
정규식 엔진에 따라 변경자의 적용 방식이 상이

  • 자바스크립트는 /패턴/i 로 쓰지만
  • 파이썬에서는 re.compile(패턴, flags=re.I) 로,
  • Java나 Go에서는 (?i)패턴으로 쓴다.

종류

  • i: 패턴을 대소문자 구분 없이 검사한다. 이 변경자를 사용할 경우 [a-z]로만 검사해도 자동으로 [a-zA-Z]와 같은 기능을 하게 된다. 영어가 아닌 언어(독일어, 프랑스어 등)를 다룰 때에는 버그 가능성이 있으므로 쓰지 않는 게 좋다. 대소문자라는 개념이 없는 한글, 한자, 가나문자는 이 패턴 변경자가 아무 역할도 하지 않는다.
  • s: 임의의 한 문자를 가리키는 . 메타 문자에 개행 문자(\n)도 포함시키도록 한다. 이 변경자를 사용하면 .이 줄바꿈도 임의의 한 문자로 취급하여 찾는다.
  • g: ^문자가 문장이 아닌 문서의 처음에, $ 문자가 문장의 끝(라인 피드 \n)이 아닌 주어진 문자열의 끝에 매치되게 변경한다.
  • m: 주어진 문자열에 줄바꿈이 있을 경우, 여러 줄로 취급하여 검사한다. (줄바꿈이 없다면 써도 의미가 없다.) 원래 정규표현식을 쓸 때 줄바꿈은 무시되는데, 이걸 사용하면 줄바꿈을 적용해서 검사한다. 그리고 ^은 한 줄의 시작, $는 한 줄의 끝으로 의미가 달라진다.
  • x: 공백 문자를 무시한다. 단, 이스케이프(역슬래쉬하고 같이 쓸 경우)하거나 문자 클래스 안에 있을 경우에는 예외. 정규식을 조금 더 읽기 편하게 만들어준다. 그러나 이 변경자를 지원하지 않는 엔진이 많은 게 단점이다.

예제

기본적인 정규식

  • /^[0-9]*$/ : 숫자
  • ^[a-zA-Z]*$ : 영문자. 패턴변경자를 써서 /^[a-z]*$/i
    같이 쓸 수 있다.
  • ^[가-힣]*$ : 현대 한글(유니코드를 지원하는 정규식 엔진에 한정)
  • ^[ㄱ-ㅎㅏ-ㅣ가-힣]*$ : 한글 자모 낱자를 포함한 모든 현대 한글
    - 굳이 유니코드 환경에서도 KS X 1001 완성형의 현대 한글 2350자만 선택하고 싶다면 완성형/한글 목록/KS X 1001 문서의 끝부분을 참고할 것.
  • ^[a-zA-Z0-9]*$ : 영문/숫자

주의점

정규식이라고 해도 각 언어에서 지원하는 정규식 엔진은 그 구현이 제각각 다르기 때문에
항상 정규식을 검증한 다음 사용해야 한다.

JavaScript

RegExp

  • exec()
  • test()

String

  • match()
  • matchAll()
  • replace()
  • replaceAll()
  • search()
  • split()

참조

RexExr

정규 표현식 MDN

Lecture 02: 형식 언어 및 정규 언어

정규표현식 (Regex) 정리

점프 투 파이썬 07장 정규표현식 07-2 정규 표현식 시작하기

//

profile
Let me introduce myself as an FE developer.

0개의 댓글