Regular Expressions Dictionary

문자열에서 특정 조건을 만족하는 문자 조합을 판별하기 위해 사용하는 표현식. (비교연산의 일종으로 이해함!)

  • 정규표현식 테스트가 가능한 사이트 : https://regexr.com/
  • 정규표현식 문제집 사이트 : https://regexone.com/

정규표현식 작성방법

· 생성

// 에 담아 생성하는 방법과, 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) 여러 조건을 표현할 때 사용한다.

    표현 의미
    | OR. 여러 조건을 OR 연산으로 병합할 때 사용한다.
    /black|white/ : black 또는 white
    [] 괄호 내 문자열 모두를 조건으로 한다.
    [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)				// return ['tata', 'tatata'] 그룹화와 수량자 + 를 사용하여 'ta'가 반복되는 경우를 표현한다.
      
    // 그룹화 예시
    'fruit: banana'.match(/(?:fruit: )([a-z]+)/)	// return ['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]
    
    • 전방 탐색 (Lookahead) /반환부분의 조건(?=탐색값)/ 위 예제와 같이 사용한다.

    • 후방 탐색 (Lookbehind) /(?<=탐색값)반환부분의 조건/

      let str = "https://github.com/"
      str.match(/(?<=\/\/)[a-z]+/) // return ['github', index: 8, input: 'https://github.com/', groups: undefined]
      
    • 부정형 전후방 탐색 (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자 사용가능
    
  • PW

    /^(?=.*\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'

※ 직접 사용해본 기능만 기재하여 posting된 기능이 전부가 아님.

참조

  • https://ko.javascript.info/
  • https://www.youtube.com/watch?v=t3M6toIflyQ&t=778s