Development/Node

javascript 정규표현식 정규식의 기본 개념 regex란

Jun Mr 2021. 10. 7. 23:13
728x90
반응형

정규표현식이란?

 

정규식, 정규표현식, regex

이 3가지로 많이 들어 보셨을겁니다.

regex는

regular(규칙적인) expression(표현) 의

줄인 표현입니다.

문자열의 특정 문자 조합과 대응을

위해 사용되는 패턴입니다.

좀더 쉽게 말해,

특정 문자를 찾아줍니다.

검색 또는 치환을 간편하게 처리할 수 있도록

특정 패턴을 작성하여 처리할 수 있습니다.

아래의 예시는

'a'를 순식간에 1로 바꿔주는 치환 예시입니다.

const test = 'asdfasdfasdfasdfasdf';
console.log(test.replace(/a/g, '1'));
// 1sdf1sdf1sdf1sdf1sdf

정규표현식의 기본

정규식을 만드는 방법은

아래와 같이 두 가지 방법이 있습니다.

"정규식 리터럴(슬래쉬"/"로 감싸는 패턴)을 사용하는 방법"
/a/

정규식 리터럴은 스크립트가 불러와질 때 컴파일이 되기때문에

정규식이 상수(고정값)라면 이렇게 사용하는 것이 성능향상에 도움됩니다.

"RegExp 객체의 생성자 함수를 호출하는 방법"
new RegExp("a");

정규식 실행 시점에 컴파일이 되기때문에

변경될 수 있는 상황에 사용될 수 있습니다.

/a/g

이런 패턴 많이 보셨나요..?

/pattern/flags

뒤에 플래그를 붙여 고급검색을 사용할 수 있습니다.

Flag 설명 예시
g 전역 검색 "a1a2a3".replace(/a/, 'z') 결과: z1a2a3
"a1a2a3".replace(/a/g, 'z') 결과: z1z2z3
i 대소문자 구분 없는 검색 "a1A2A3".replace(/a/g, 'z') 결과: z1A2A3
"a1A2A3".replace(/a/gi, 'z') 결과: z1z2z3
m 다중행(multi-line) 검색 `a1a2a3
a4a5a6`.replace(/3$/g, 'z') ($는 문장끝 위치검색)
결과:
"a1a2a3
a4a5a6"

`a1a2a3
a4a5a6`.replace(/3$/gm, 'z')
결과:
"a1a2az
a4a5a6"
s .에 개행 문자도 매칭(ES2018) `a1.a2\na3`.replace(/./g, 'z') 결과: "zzzzz\nzz"
`a1.a2\na3`.replace(/./gs, 'z') 결과: "zzzzzzzz"
(. 은 모든 단어와 대응되는 특수문자 - 아래에서 자세히)
u 유니코드; 패턴을 유니코드 코드 포인트의 나열로 취급 `a1a2a3`.replace(/\p{N}/g, 'z') 결과: "a1a2a3"
`a1a2a3`.replace(/\p{N}/gu, 'z') 결과: "azazaz"
(\p{...} 유니코드 범주 사용)
y "sticky" 검색을 수행. 문자열의 현재 위치부터 검색 var str = 'aaabb';
var regex = /a/y;
regex.lastIndex=2;
regex.test(str); //true < aaabb 찾음
regex.test(str); //false < 찍고 초기화
regex.test(str); //true < aaabb 찾음
regex.test(str); //true < aaabb 찾음
regex.test(str); //true < aaabb 찾음
regex.test(str); //false < aaabb 찍고 초기화

유니코드 문자 범주 및 각각의 하위 범주 목록

*문자(Letter) [L]

  -소문자(lowercase) [Ll] ex) `a1b2A3C4`.replace(/\p{Ll}/gu, 'z') // "z1z2A3C4"

  -조정(modifier) [Lm]

  -단어의 첫 글자를 대문자로(titlecase) [Lt]

  -대문자(uppercase) [Lu]

  -기타(other) [Lo]

*숫자(Number) [N]

  -10진수(decimal digit) [Nd]

  -문자(letter number) [Nl]

  -기타(other) [No]

*문장 부호(Punctuation) [P]

  -연결선(connector) [Pc]

  -대시(dash) [Pd]

  -처음 따옴표(initial quote) [Pi]

  -마지막 따옴표(final quote) [Pf]

  -열기(open) [Ps]

  -닫기(close) [Pe]

  -기타(other) [Po]

*표시(Mark) [M] (강세 등)

  -간격 결합(spacing combining) [Mc]

  -묶음(enclosing) [Me]

  -비공백(non -spacing) [Mn]

*기호(Symbol) [S]

  -통화(currency) [Sc]

  -수정(modifier) [Sk]

  -수학(math) [Sm]

  -기타(other) [So]

*구분 기호(Separator) [Z]

  -줄(line) [Zl]

  -단락(paragraph) [Zp]

  -공백(space) [Zs]

*기타(Other) [C]

  -제어(control) [Cc]

  -형식(format) [Cf]

  -할당되지 않음(not assigned) [Cn]

  -사용자 지정(private use) [Co]

  -서로게이트(surrogate) [Cs]

정규식에서의 특수문자

특수문자 설명 예시
\(\ 백슬래쉬) 특수문자를 특별하지 않고,
문자 그대로 해석을 가리킴.
`A1b2^A3C4`.replace(/^A/g, 'z');
// "z1b2^A3C4"
`A1b2^A3C4`.replace(/\^A/g, 'z');
// "A1b2z3C4"
^ 시작부분에 대응. `A1b2A3C4`.replace(/^A/g, 'z');
// "z1b2A3C4"
$ 끝 부분에 대응. `A1b2^A3C4A`.replace(/A$/g, 'z');
// "A1b2^A3C4z"
* 0회 이상 연속되는 부분과 대응. `111aaaa`.replace(/1a*/g, 'z');
// "zzz"
+ 1회 이상 연속되는 부분과 대응. `111aaaa`.replace(/1a+/g, 'z');
// "11z"

.....

아래 더 자세하고 많은 내용 참고

https://developer.mozilla.org/ko/docs/Web/JavaScript/Guide/Regular_Expressions

 

정규 표현식 - JavaScript | MDN

정규 표현식은 문자열에 나타는 특정 문자 조합과 대응시키기 위해 사용되는 패턴입니다. 자바스크립트에서, 정규 표현식 또한 객체입니다.  이 패턴들은 RegExp의 exec 메소드와 test 메소드  ,

developer.mozilla.org

 

특수문자 설명
* 앞의 표현식이 0회 이상 연속으로 반복되는 부분과 대응됩니다. {0,} 와 같은 의미입니다.
예를 들어, /bo*/ 는 "A ghost booooed" 의 'boooo' 와 대응되고, "A bird warbled" 의 'b'에 대응되지만 "A goat grunted" 내의 어느 부분과도 대응되지 않습니다.
+ 앞의 표현식이 1회 이상 연속으로 반복되는 부분과 대응됩니다. {1,} 와 같은 의미입니다.
예를 들어, /a+/ 는 "candy"의 'a'에 대응되고 "caaaaaaandy" 의 모든 'a'들에 대응되지만, "cndy" 내의 어느 부분과도 대응되지 않습니다.
? 앞의 표현식이 0 또는 1회 등장하는 부분과 대응됩니다. {0,1} 와 같은 의미입니다.

예를 들어, /e?le?/ 는 "angel"의 'el' 에 대응되고, "angle"의 'le' 에 대응되고 또한 "oslo" 의 'l'에도 대응됩니다.

만약 수량자 *, +, ?, {} 바로 뒤에 사용하면, 기본적으로 탐욕스럽던(가능한 한 많이 대응시킴) 수량자를 탐욕스럽지 않게(가능한 가장 적은 문자들에 대응시킴) 만듭니다. 예를 들어, /\d+/를 "123abc"에 적용시키면 "123"과 대응됩니다. 그러나 /\d+?/를 같은 문자열에 적용시키면 오직 "1"과만 대응됩니다.

또한 이 문자는 x(?=y) 와 x(?!y) 항목에서 설명하는 바와 같이 사전 검증(lookahead assertion)을 위해서도 쓰입니다.

. 개행 문자를 제외한 모든 단일 문자와 대응됩니다.
예를 들어, /.n/는 "nay, an apple is on the tree"에서 'an'과 'on'에 대응되지만, 'nay' 에는 대응되지 않습니다.
(x) 다음의 예제가 보여주는것 처럼 'x'에 대응되고, 그것을 기억합니다. 괄호는 포획 괄호(capturing parentheses)라 불립니다.

패턴 /(foo) (bar) \1 \2/ 안의 '(foo)' 와 '(bar)'는 문자열"foo bar foo bar"에서 처음의 두 단어에 대응되고 이를 기억합니다. 패턴 내부의 \1와 \2는 문자열의 마지막 두 단어에 대응됩니다. (역주: \n 패턴은 앞의 n번째 포획괄호에 대응된 문자열과 똑같은 문자열에 대응됩니다.) \1, \2, \n과 같은 문법은 정규식의 패턴 부분에서 사용됩니다. 정규식의 치환 부분에서는 $1, $2, $n과 같은 문법이 사용되어야 합니다. 예를 들어, 'bar foo'.replace( /(...) (...)/, '$2 $1')와 같이 사용되어야 합니다. $& 패턴은 앞에서 대응된 전체 문자열을 가리킵니다.
(?:x) 'x'에 대응되지만 대응된 것을 기억하지 않습니다. 괄호는 비포획 괄호(non-capturing parentheses)라고 불리우고, 정규식 연산자가 같이 동작할 수 있게 하위 표현을 정의할 수 있습니다. 정규식 예제 /(?:foo){1,2}/을 생각해보세요. 만약 정규식이 /foo{1,2}/라면, {1,2}는 'foo'의 마지막 'o' 에만 적용됩니다. 비포획 괄호과 같이 쓰인다면, {1,2}는 단어 'foo' 전체에 적용됩니다.
x(?=y) 오직 'y'가 뒤따라오는 'x'에만 대응됩니다. 이것은 lookahead 라고 불립니다.
예를 들어, /Jack(?=Sprat)/ 는 'Sprat'가 뒤따라오는 'Jack' 에만 대응됩니다. /Jack(?=Sprat|Frost)/는 'Sprat' 또는 'Frost'가 뒤따라오는 'Jack'에만 대응됩니다. 그러나, 'Sprat' 및 'Frost' 는 대응 결과의 일부가 아닙니다.
x(?!y) 'x'뒤에 'y'가 없는경우에만 'x'에 일치합니다. 이것은 negated lookahead 라고 불립니다.
예를 들어, /\d+(?!\.)/는 소숫점이 뒤따라오지 않는 숫자에 일치합니다. 정규식 /\d+(?!\.)/.exec("3.141")는 '3.141' 이 아닌 '141'에 일치합니다.
x|y 'x' 또는 'y'에 대응됩니다.
예를 들어, /green|red/는 "green apple"의 'green'에 대응되고, "red apple."의 'red'에 대응됩니다.
{n} 앞 표현식이 n번 나타나는 부분에 대응됩니다. n은 반드시 양의 정수여야 합니다.

예를 들어, /a{2}/는 "candy,"의 'a'에는 대응되지 않지만, "caandy,"의 모든 a 와, "caaandy."의 첫 두 a 에는 대응됩니다.
{n,m} n과 m은 양의 정수이고, n <= m를 만족해야 합니다. 앞 문자가 최소 n개, 최대 m개가 나타나는 부분에 대응됩니다. m이 생략된다면, m은 ∞로 취급됩니다.
예를 들어, /a{1,3}/는 "cndy"에서 아무것에도 대응되지 않지만, "caandy,"의 첫 두 a 와 "caaaaaaandy"의 첫 세 a 에 대응됩니다. "caaaaaaandy"에서 더 많은 a 들이 있지만, "aaa"에만 대응된다는 점에 주목하세요.
[xyz] 문자셋(Character set) 입니다. 이 패턴 타입은 괄호 안의 어떤 문자(이스케이프 시퀀스까지 포함)와도 대응됩니다. 점(.) 이나 별표 (*) 같은 특수 문자는 문자셋 내부에서는 특수 문자가 아닙니다. 따라서 이스케이프시킬 필요가 없습니다. 하이픈을 이용하여 문자의 범위를 지정해줄 수 있습니다.

예를 들어, 패턴 [a-d] 는 패턴 [abcd] 와 똑같이 동작하며, "brisket"의 'b' 에 일치하고, "city"의 'c' 에 일치합니다. 패턴 /[a-z.]+/ 와 /[\w.]+/ 는 "test.i.ng" 전체 문자열이 일치합니다.
[^xyz] 부정 문자셋(negated character set) 또는 보충 문자셋(complemented character set)입니다. 괄호 내부에 등장하지 않는 어떤 문자와도 대응됩니다. 하이픈을 이용하여 문자의 범위를 지정할 수 있습니다. 일반적인 문자셋에서 작동하는 모든 것은 여기에서도 작동합니다.
예를 들어, 패턴[^abc]는 패턴[^a-c]와 동일합니다. 두 패턴은 "brisket"의 'r', "chop."의 'h' 에 대응됩니다.
[\b] 백스페이스(U+0008)에 대응됩니다. 이와 같이, 백스페이스 문자 리터럴에 대응시키려면, 대괄호("[]")를 이용해야만 합니다. (\b와 혼동하지 마세요.)
\b 단어 경계에 대응됩니다. 단어 경계는 다른 '단어 문자'가 앞이나 뒤에 등장하지 않는 위치에 대응됩니다. 단어의 경계는 대응 결과에 포함되지 않는다는 사실에 주의하세요. 다른 말로는, 단어의 경계에 대응되는 문자열의 길이는 항상 0입니다. (패턴 [\b]와 혼동하지 마세요.)
예제:
/\bm/는 "moon"의 'm'에 대응됩니다;
/oo\b/ 는 "moon"의 'oo' 부분에 대응되지 않는데, 왜냐하면 'oo'를 뒤따라오는 'n'이 단어 문자이기 때문입니다;
/oon\b/는 "moon"의 'oon'에 대응됩니다. 왜냐하면, 'oon'은 문자열의 끝이라서, 뒤따라오는 단어 문자가 없기 때문입니다 ;
/\w\b\w/는 어떤 것에도 일치하지 않습니다. 왜냐하면, 단어 문자는 절대로 비 단어 문자와 단어 문자 두개가 뒤따라올수 없기 때문입니다.
숙지하세요: 자바스크립트의 정규식 엔진은 특정 문자 집합을 '단어 문자'로 정의합니다. 이 집단에 속하지 않는 모든 문자는 단어 분리(word break) 로 여겨집니다. 단어 문자로 간주되는 문자들은 얼마 없습니다: 오로지 로마자 소문자와 대문자, 10진수 숫자, 밑줄 문자로 구성되어 있습니다. "é" 또는 "ü" 같이, 강세 표시 문자들은 안타깝게도 단어 분리(word breaks) 로 취급됩니다.
\B 단어 경계가 아닌 부분에 대응됩니다. 아래와 같은 경우들이 있습니다:
문자열의 첫 번째 문자가 단어 문자가 아닌 경우, 해당 문자의 앞 부분에 대응됩니다.
문자열의 마지막 문자가 단어 문자가 아닌 경우, 해당 문자의 뒷 부분에 대응됩니다.
두 단어 문자의 사이에 대응됩니다.
단어 문자가 아닌 두 문자 사이에 대응됩니다.
빈 문자열에 대응됩니다.
문자열의 시작 부분과 끝 부분은 단어가 아닌 것으로 간주됩니다.
예를 들어, /\B../ 는 "noonday"의 'oo'와 대응되며, /y\B./ 는 "possibly yesterday."의 'ye'와 대응됩니다.
\cX 문자열 내부의 제어 문자에 대응됩니다. 여기서 X는 A에서 Z까지의 문자 중 하나입니다.
예를 들어, /\cM/는 문자열에서 control-M (U+000D)에 대응됩니다.
\d 숫자 문자에 대응됩니다. [0-9]와 동일합니다.
예를 들어, /\d/ 또는 /[0-9]/는 "B2 is the suite number."에서 '2'에 대응됩니다.
\D 숫자 문자가 아닌 문자에 대응됩니다. [^0-9]와 동일합니다.
예를 들어, /\D/ 또는 /[^0-9]/는 "B2 is the suite number."의 'B'에 대응됩니다.
\f 폼피드 (U+000C) 문자에 대응됩니다.
\n 줄 바꿈 (U+000A) 문자에 대응됩니다.
\r 캐리지 리턴(U+000D) 문자에 대응됩니다.
\s 스페이스, 탭, 폼피드, 줄 바꿈 문자등을 포함한 하나의 공백 문자에 대응됩니다. [ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff].와 동일합니다.
예를 들어, /\s\w*/는 "foo bar."의 ' bar'에 대응됩니다.
\S 공백 문자가 아닌 하나의 문자에 대응됩니다. [^ \f\n\r\t\v\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]. 와 동일합니다.
예를 들어, /\S\w*/는 "foo bar."의 'foo' 에 대응됩니다.
\t 탭 (U+0009) 문자에 대응됩니다.
\v 수직 탭(U+000B) 문자에 대응됩니다.
\w 밑줄 문자를 포함한 영숫자 문자에 대응됩니다. [A-Za-z0-9_] 와 동일합니다. (역주: 여기에 대응되는 문자를 단어 문자라고 합니다.)
예를 들어, /\w/는 "apple,"의 'a' 에 대응되고, "$5.28,"의 '5'에 대응되고,"3D."의 '3'에 대응됩니다.
\W 단어 문자가 아닌 문자에 대응됩니다. [^A-Za-z0-9_] 와 동일합니다.
예를 들어, /\W/ 또는 /[^A-Za-z0-9_]/는 "50%."의 '%' 에 대응됩니다.
\n 정규식 내부의 n번째 괄호에서 대응된 부분에 대한 역참조 입니다. 여기서, n은 양의 정수입니다.
예를 들어, /apple(,)\sorange\1/는 "apple, orange, cherry, peach."의 'apple, orange,' 에 일치합니다.
\0 널 (U+0000)문자에 대응합니다. 이 때 다른 숫자를 뒤에 쓰지 마세요. 왜냐하면 \0<digits>는 8진 이스케이프 시퀀스이기 때문입니다.
\xhh 코드가 hh(두 16진 숫자)인 문자에 일치합니다.
\uhhhh 코드가 hhhh(네개의 16진 숫자)인 문자에 일치합니다.

정규식과 함께 사용되는 메소스

메소드 설명 예시
exec (RegExp) 대응되는 문자열을 찾음. 정보를 배열로 반환. /a/g.exec('abcd');
// ["a", index: 0, input: "abcd", groups: undefined]
test (RegExp) 대응되는 문자열 검사.
true, false 반환.
/a/g.test('abcd');
// true
match (String) 대응되는 문자열을 찾아 배열로 반환. 'abcda'.match(/a/g);
// (2) ["a", "a"]
search (String) 대응되는 문자열의 인덱스를 반환. 찾지 못하면 -1 'abcda'.search(/a/g);
// 0
'bcda'.search(/a/g);
// 3
replace (String) 대응되는 문자열 치환 'abcda'.replace(/a/g, 1);
// "1bcd1"
split (String) 대응되는 문자열로 나누어 배열로 반환 `a1a2a3a4`.split(/a/g);
(5) ["", "1", "2", "3", "4"]

다음 포스팅은

정규식을 활용한 여러 사용예시를

작성하려고 합니다.

반응형