수량자
어떠한 패턴이 얼만큼 등장하는지 숫자를 나타내는 것으로, * / + / ? 세 가지 표현 방법이 있다.
*는 0 또는 여러 개
+는 1 또는 여러 개
?는 0 또는 1을 나타낸다.
수량자 뒤에 있는 문자를 기준으로 생각하는 것이 편리하다.
아래 예시로 보다 정확하게 이해해보자.
✏️ 예시)
[Case 1] a*b
- b 앞에 문자가 0번 나오거나 여러 개 있는 것이 선택된다.
- 즉 b 앞에 문자가 1개, 2개, 3개... 여러 개 있어도 선택되고, 문자가 하나도 없어도 선택된다.
[Case 2] a+b
- b 앞에 문자가 최소 1번은 나와야 한다.
- 앞에 문자가 아무 것도 없는 b는 선택되지 않는다.
[Case 3] a?b
- b 앞에 문자가 없거나 1번 있어야 한다.
- b 앞에 문자가 여러 개일 경우에는 선택되지 않는다.
다른 예시로도 확인해보자.
✏️ 예시)
[Case 1] .*
- '*'는 0부터 여러 개를 포괄한다. 따라서 앞에 점이 있다면 모든 문자를 선택한다는 뜻이 된다.
[Case 2] -A*-
- '-' 앞에 A가 없을 수도 있고, 하나일 수도 있고, 여러 개일수도 있다는 뜻이다.
- * 앞의 A는 있어도 되고 없어도 되기 때문에 '--' 으로 선택된다.
[Case 3] [-@]*
- 대괄호는 '-' 나 '@'면 선택된다는 뜻으로, 대괄호 안에 있는 문자가 없을 수도 있고 여러번 반복될 수도 있다.
- 그래서 '-@-' 도 선택되고, '--'도 선택되는 것이다.
더하기 부호의 예시도 살펴 보자.
더하기 부호는 1 또는 여러 개를 나타냈다.
✏️ 예시)
[Case 1] \*+
- 백슬래시 뒤에 있는 *는 단순 문자 *로만 기능한다.
- 따라서 *가 1개 또는 여러 개 있을 경우에 선택된다.
[Case 2] -@+-
- 앞과 뒤는 반드시 '-'가 와야 하며 + 앞의 @는 1개 또는 여러 개여야 한다.
[Case 3] [^ ]+
- 대괄호 안의 ^는 선택되지 않는다 = not을 뜻한다.
- ^ 뒤에 공백이 있기 때문에, 공백이 아닌 것이 1개 또는 여러 개여야 한다.
- 즉 공백이 아닌 모든 문자들이 선택된다.
마지막으로 물음표에 대한 예시도 들어보자.
물음표는 0 또는 1을 나타낸다.
✏️ 예시)
[Case 1] -X?XX?X
- 앞에는 반드시 '-'가 와야 하며 물음표 앞은 없거나 1개만 있어야 한다.
- 따라서 X?XX?X 라면 볼드 처리된 부분의 X가 없거나 1개만 있어야 한다.
- 있다고 하면 -XXXX 인데 그만큼 있지 않고, 없다 치면 필수적인 -XX 가 선택된다.
[Case 2] -@?@?@?-
- 똑같이 앞뒤에는 반드시 '-'가 와야 하며 물음표 앞은 없거나 1개만 있어야 한다.
- @?@?@? 에서 @는 없어도 되고 1개만 있어도 된다.
- 즉 없는 경우 -- / 1개만 있는 경우 -@- / 2개 있는 경우 -@@- / 3개 있는 경우 -@@@- 이 선택될 수 있다.
[Case 3] [^@]@?@
- 대괄호 안의 ^뒤는 선택되지 않는다. 즉 @만 아니면 선택된다.
- @?@에서 앞의 @는 없거나 1개만 있어야 하고, 뒤의 @는 반드시 있어야 한다.
- 즉 @가 아닌 것 + @가 없거나 1개 있는 것 + @ 만 선택된다.
수량자 2 (중괄호 {})
중괄호 {}를 활용한 수량자는 중괄호 안에 내가 원하는 수량을 정확하게 지정하여 사용할 수 있는 수량자다.
{n} 는 문자 n개를, {min, max}처럼 숫자가 2개인 경우에는 최소 ~ 최대, {m,}는
✏️ 예시)
[Case 1] .{5}
- '.'은 any character로 모든 문자를 의미한다. 중괄호 안의 수가 5이므로 앞부터 문자 5개씩 끊어간다.
- All matches의 경우에도 문자 5덩어리씩 끊었을 때 남는 것이 m이라서 m 은 선택되지 않았다.
[Case 2] [els]{1,3}
- 대괄호 안의 e 또는 l 또는 s가 1개 이상 3개 이하일 경우 선택된다.
[Case 3] [a-z]{3,}
- 대괄호 안의 a-z는 a~z까지를 의미한다. 뒤에 숫자가 3만 있는 이 식은 소문자가 최소 3개 이상일 경우를 뜻한다.
- 그래서 All matches에서 One이 선택되지 않은 것이며, 문자 수가 3보다 작은 to, in 역시 선택되지 않은 것이다.
처음에 배웠던 *, +, ? 도 중괄호를 사용해서 선택할 수 있다.
✏️ 예시)
[Case 1] AB*A
- *는 0 또는 여러 개로 AA 또는 AB...BA 의 형태여야 한다.
[Case 2] AB{0,}A
- 앞뒤 AA는 반드시 있어야 하며, B는 최소 0개 이상 있어야 한다. (=없어도 된다.)
[Case 3] AB+A
- +는 1 또는 여러 개로 ABA 또는 AB...BA의 형태여야 한다.
[Case 4] AB{1,}A
- 마찬가지로 앞뒤 AA는 갖고 있되 가운데의 B가 최소 1개 이상 있어야 한다.
[Case 5] AB?A
- ?는 0 또는 1개로 AA 또는 ABA여야 한다.
[Case 6] AB{0,1}A
- AA는 갖고 있되 중간의 B는 최소 0개 ~ 최대 1개를 선택할 수 있다.
탐욕적인 수량자(Greedy quantifier)와 게으른 수량자(Lazy quantifier)
수량자 + '?'의 형태가 되면 위에서 배운 수량자의 의미가 달라진다.
밑에서 예시를 통해 이해해보자.
✏️ 예시)
[Case 1] r.*
- '.'은 모든 문자를 뜻하므로 r로 시작하는 모든 문자를 선택할 수 있다.
- '*'는 없거나 여러 개 이기 때문에 예시와 같이 r로 시작한 문장이 쭉 선택된 것이다.
[Case 2] r.*?
- '*' + '?'의 경우 의미가 달라져 '*'는 0~1~여러 개 / '?'는 0~1의 의미를 갖고 있는데, 둘이 만나면 *는 최솟값을 가져온다.
- 즉 r로 시작, 그 뒤에는 모든 문자가 올 수 있지만 *? 때문에 0개가 와서 모든 문자는 0개 = 오지 않는다.
- 그래서 r만 선택되는 것이다.
✏️ 예시)
[Case 3] r.+
- '+'는 1 또는 여러 개로, r로 시작해 모든 문자가 1 또는 여러 개 붙는 형태가 선택된다.
[Case 4] r.+?
- 마찬가지로 '+' + '?'의 경우 본래 의미가 달라져 r로 시작한 모든 문자를 선택하되 1개만 선택할 수 있다. (+의 최솟값)
✏️ 예시)
[Case 5] r.?
- '?'는 0 또는 1개를 뜻한다. 그래서 r로 시작해 뒤에 붙는 아무 문자의 개수가 0 또는 1개로 선택된다.
[Case 6] r.??
- 마찬가지로 r로 시작하되 뒤에 붙는 아무 문자의 개수가 '?'의 최솟값인 0개이므로 r만 선택된다.
그래서 왜 이 '?'연산자를 사용하며 뭐가 그리디 수량자고 뭐가 레이지 수량자냐면...
<div>test</div><div>test2</div> 가 있을 때
1) <div>.+</div>
- <div>로 시작하고 </div> 끝나되 '.' 때문에 사이에 모든 문자가 들어갈 수 있고, 개수는 1개 또는 여러 개가 들어갈 수 있다.
- 그래서 해당 줄 모두가 선택된다.
- test 에 관한 div만 선택하고 싶었는데... 처음부터 끝까지 넓은 범위로 다 먹어버리기에 이런 놈이 탐욕적인 연산자가 된다.
2) <div>.+?</div>
- '+'가 1개 또는 여러 개를 선택할 수 있는데 뒤에 '?'를 만나 최소 1개만 선택할 수 있게 된다.
- 이걸 문자 1개 라고 보기보다 한 덩어리의 개념으로 이해해야 한다.
- 그래서 <div>test</div>만 선택할 수 있게 된다.
- 상대적으로 게으른 이런 놈을 게으른 연산자라고 한다.
'👋🏻 JavaScript > 📖 자바스크립트 ES6+' 카테고리의 다른 글
[JavaScript] map() 이란? (0) | 2023.04.25 |
---|---|
[JavaScript] splice와 slice 비교하기 (0) | 2023.04.19 |
[JavaScript] 정규 표현식 공부하기 3 (0) | 2023.03.26 |
[JavaScript] 정규 표현식 공부하기 1 (0) | 2023.03.26 |
[JavaScript] 자바스크립트로 입력 받기 (0) | 2023.03.25 |