본문 바로가기
Languages

[JavaScript] 정규표현식 (RegExp)

by roses16 2023. 7. 2.

Regular expressions dictionary

문자열에서 특정 조건을 만족하는 문자 조합을 판별하기 위해 사용하는 표현식.


정규표현식 작성방법

생성

/ / 에 담아 생성하는 방법과, new RegExp() 함수를 사용하는 방법이 있다.

let re = /정규표현식/플래그
let re = new RegExp('정규표현식', '플래그')

플래그

검색범위 등 정규표현식으로 정의하기 어려운 검색 조건을 설정한다.

let re = /정규표현식/gm
// 플래그 g와 m의 기능을 사용하겠다는 의미. 자세한 기능설명은 하단 표 참조

 

플래그 설명 대응하는 속성
g Global 전역탐색. 패턴과 일치하는 모든 경우를 찾는다. RegExp.prototype.global
i Case insensitive 대/소문자를 구분하지 않는다. RegExp.prototype.ignoreCase
m Multiline 다중 행 검색
정규 표현식 ^, $ 가 각 행의 시작과 끝에도 대응한다.
default는 전체 문자열의 시작과 끝에만 대응한다.
RegExp.prototype.multiline
s Single line 정규 표현식 . 이 개행문자를 포함한다. RegExp.prototype.dotAll
u Unicode 유니코드 전체를 지원한다.
default 는 2바이트 유니코드 만을 정상적으로 지원한다.
4바이트 유니코드 문자 (😎, 𝒳 등) 를 사용한다면 u플래그 사용이 필요하다.
RegExp.prototype.unicode
y Sticky 접착탐색  RegExp.prototype.sticky

※ 대응하는 속성 : 해당 플래그 설정 여부를 Boolean 값으로 가지고 있다.

 

정규표현식 문법

문자열 검색

검색하고자하는 문자열을 // 안에 담아 표현한다.

let str = 'Victory belongs to the most persevering.'
str.match(/to/gm)	// return ['to', 'to']
// ▶ match()는 정규표현식 조건에 부합하는 문자열을 반환한다. Victory의 to와 to가 검색되었다.

 

문자 클래스(Character classes)

문자의 타입(숫자, 문자, 특수문자 등)을 조건으로 표현할 때 사용한다.

 

표현 의미
\ 특수문자가 아닌 문자
. 개행문자를 제외한 모든 문자 (영문/숫자/특수문자 포함)
단, 플래그 s 사용 시 개행문자도 포함
\d 숫자
\D 숫자를 제외한 문자
\w 숫자, 문자, 특수문자 _
\W 숫자, 문자 특수문자 _ 를 제외한 문자
\s 공백 (space)
\S 공백 (space)를 제외한 문자
let re = /\d/g	// " \d " 사용. 숫자를 조건으로 하는 표현식
'a12'.match(re)	// return ['1', '2']
'abc'.match(re)	// return null

 

그룹과 범위(Groups and ranges)

여러 조건을 표현할 때 사용한다.

표현 의미
[ ] 괄호 내 문자열 모두를 조건으로 한다.
[abc] : a 또는 b 또는 c [a-zA-Z0-9] : a, b, c ... z, A, B, C ... Z, 0, 1, 2 ... 9
[ ^ ] 위 [ ] 의 부정문 형태
[^abc] : a, b, c를 제외한 나머지
()
(?<Group name>)
일정 조건을 그룹화하여 캡처한다.
캡처는 성능저하가 생길 수 있으므로 캡처가 필요하지 않은 경우 아래 (?:)를 사용하여 그룹화한다.
(?:) 캡처 없이 그룹화를 진행한다.
let str = 'John 1:5 The light shines in the darkness.'
str.match(/light|dark/g)		// return ['light', 'dark']
str.match(/[0-9\.]/g)			// return ['1', '5', '.']

str = 'Ra-tata, grra-tatata from.pink venom'
str.match(/(ta)+/g)
// ['tata', 'tatata'] 그룹화와 수량자 + 를 사용하여 'ta'가 반복되는 경우를 표현한다.

// 그룹화 예시
'fruit: banana'.match(/(?:fruit: )([a-z]+)/)
// ['fruit: banana', 'banana', index: 0, input: 'fruit: banana' ...]
// 입력 양식은 알고 있으나 과일 이름을 모를 때, 과일 이름 부분만 그룹화하여 return 받는 배열의 [1]인덱스로 받을 수 있다. 그룹이 많을 경우 인덱스 번호도 늘어난다.

 

수량자(Quantifiers)

이미 작성된 조건에 횟수, 양에 대한 조건을 더한다.

표현 의미
? zero or one. {0, 1}과 같다.
* zero or more. {0, }과 같다.
+ one or more. {1, } 과 같다.
{n} n번 반복
{min,} 최소
{min,max} 최소와 최대

 

'w ww www vv'.match(/w?/g)		// return ['w', '', 'w', 'w', '', 'w', 'w', 'w', '', '', '', '']
'w ww www vv'.match(/w*/g)		// return ['w', '', 'ww', '', 'www', '', '', '', '']
'w ww www vv'.match(/w+/g)		// return ['w', 'ww', 'www']
'w ww www vv'.match(/w{3,}/g))	// return ['www']

 

Boundary-Type assertions

이미 작성된 조건에 위치 조건을 더한다.

표현 의미
\b 단어 시작
\B 단어 시작이 아님
^ 문자열의 시작. m 플래그가 설정되어있다면 문장의 시작
$ 문자열의 끝. m 플래그가 설정되어있다면 문장의 끝

 

'far as tea'.match(/\ba/)	// return ['a', index: 4] → as의 a
'sea tea'.match(/^t/)		// return null

 

전후방탐색(Lookaround)

검색 조건에 포함하되, 결과값에서 제외할 때 사용한다.


특별한 형식이 정해져있지 않은 예시 "2022년 0월 2020원" 에서 금액의 단위를 제외한 숫자만을 가져오려면 '원' 이라는 문자를 검색에 포함시켜야한다. 즉, 단위와 함께 그룹화가 되어 원하지 않은 결과값이 반환된다. 이 때 아래와 같이 전후방탐색을 사용한다.

// 전방탐색

let str = "2022년 9월 2020원"
str.match(/\d+(?=원)/)
// return ['2020', index: 9, input: '2022년 0월 2020원', groups: undefined]

 

// 후방탐색

let str = "https://github.com/"
str.match(/(?<=\/\/)[a-z]+/)
// return ['github', index: 8, input: 'https://github.com/', groups: undefined]
  • 전방 탐색(Lookahead) : /반환부분의 조건(?=탐색값)/ 
  • 후방 탐색(Lookbehind) : /(?<=탐색값)반환부분의 조건/

 

부정형 전후방 탐색(Negative lookaround)

  • 부정형 전방탐색 : /반환부분의 조건(?!탐색값)/
  • 부정형 후방탐색 : /(?<!탐색값)반환부분의 조건/
let str = "-50+100 /30"
str.match(/\b(?<!-)\d+/)
// return ['100', index: 5, input: '-50 +100 /30', groups: undefined]

자주 사용하는 정규표현식

ID

/^(?=.*[a-zA-Z])[-a-zA-Z0-9_.]{2,10}$/
// ^(?=.*[a-zA-Z]) : a-z, A-Z는 꼭 들어가야한다.
// → 시작부터 탐색해서〔^〕 모든 문자가〔.〕많든, 혹은 없든〔*〕[a-zA-Z]보다 앞에 있는 걸 탐색한다.〔(?=)〕즉, [a-zA-Z]가 없으면 탐색이 안된다.
// [-a-zA-Z0-9_.]{2,10} : a-z, A-Z, 0-9, -, _, . 문자열을 최소 2자, 최대 10자 사용가능

Password

/^(?=.*\d)(?=.*[a-zA-Z])[0-9a-zA-Z!@#$%^&*]{8,20}$/

Method

정규표현식은 RegExp 객체와 String 객체의 Method에서 사용된다.

 

RegExp.prototype.test()

정규표현식 조건에 부합하는지 Boolean 값으로 반환한다.

 

new RegExp(/a/).test('abc')		// return true

 

String.prototype.match()

정규표현식 조건에 부합하는 값 및 값에 대한 정보를 반환한다.

 

'fruit: banana'.match(/a/)
// return ['a', index: 8, input: fruit: banana, groups]
'fruit: banana'.match(/a/g)
// return ['a', 'a', 'a']
// → 전역플래그(g) 설정에 따라 반환값이 다르다.

 

String.prototype.replace()

정규표현식 조건에 부합하는 값을 입력받은 Text 또는 함수의 return 값으로 대체한다.

 

let str = 'abc'
str.replace(/a/, 'A')// return 'Abc'
str.replace(/b/, e => e.toUpperCase())	// return 'aBc'

 

※ 사용해본 Method만 정리했으며, 전체 Method는 MDN에서 확인가능.


📌 참조