iBetter Books
수정

확장 정규표현식 (ERE)

BRE에서 "1번 이상"을 표현하려면 \+라고 써야 합니다. \가 많아질수록 패턴이 읽기 어려워집니다. ERE(Extended Regular Expression, 확장 정규표현식)는 이런 이스케이프를 없애고, 더 직관적인 메타문자를 제공합니다.

grep에서 ERE를 쓰려면 -E 옵션을 붙이거나, egrep 명령어를 씁니다.

ERE에서 추가된 메타문자

메타문자 의미 BRE 비교
+ 앞 문자 1번 이상 반복 BRE: \+
? 앞 문자 0번 또는 1번 BRE: \?
| 또는 (OR) BRE 없음
() 그룹화 BRE: \(\)
{n} 정확히 n번 반복 BRE: \{n\}
{n,m} n번 이상 m번 이하 BRE: \{n,m\}

BRE vs ERE 비교표

기능 BRE ERE (grep -E)
1번 이상 \+ +
0 또는 1번 \? ?
또는 (없음) |
그룹 \(\) ()
정확히 3번 \{3\} {3}
2~5번 \{2,5\} {2,5}

수량자 정리

수량자(quantifier)는 앞 문자나 그룹이 몇 번 나타나는지 지정합니다.

수량자 의미 예시
* 0번 이상 ab*c → ac, abc, abbc
+ 1번 이상 ab+c → abc, abbc (ac는 아님)
? 0 또는 1번 ab?c → ac, abc (abbc는 아님)
{3} 정확히 3번 a{3} → aaa
{2,4} 2번 이상 4번 이하 a{2,4} → aa, aaa, aaaa
{2,} 2번 이상 a{2,} → aa, aaa, aaaa...
# sample.txt에서 연습# "err" 이후 o가 0번 이상 (BRE와 동일)grep -E "erro*" /tmp/sample.txt
error
errors
err
# "err" 이후 o가 1번 이상 (ERE의 +)grep -E "erro+" /tmp/sample.txt
error
errors

"err"는 o가 없으므로 제외되었습니다.

# 3~4자리 단어만 (앞뒤 앵커 활용)grep -E "^.{3,4}$" /tmp/sample.txt
cat
car
cab
bat
can
cart
card
care
bare
bar
err

OR 연산자 |

# cat 또는 batgrep -E "cat|bat" /tmp/sample.txt
cat
bat
# 오류 관련 단어 모두 찾기grep -E "error|err|errors" /tmp/sample.txt
error
errors
err

순서 주의: errors|error|err처럼 긴 패턴을 먼저 쓰는 것이 더 명확합니다. 하지만 ERE에서 |의 우선순위는 낮아서 errors|error는 "errors 또는 error"입니다.

그룹화 ()

# "car" 또는 "bar" (앞부분이 c 또는 b)grep -E "(c|b)ar" /tmp/sample.txt
car
cart
card
care
bare
bar
# "cart" 또는 "card" 또는 "care" (car 뒤에 t, d, e 중 하나)grep -E "car(t|d|e)" /tmp/sample.txt
cart
card
care

앵커 확장

BRE와 ERE 모두 단어 경계를 표현하는 앵커를 씁니다.

앵커 의미
\b 단어 경계
\< 단어 시작
\> 단어 끝
# "bar"가 독립 단어로 있는 줄 (bar123은 제외)grep -E "\bbar\b" /tmp/sample.txt
bar

bar123은 "bar" 뒤에 숫자가 이어지므로 단어 경계가 아닙니다.

# 단어 시작이 "car"인 것grep -E "\<car" /tmp/sample.txt
car
cart
card
care

역참조 \1

그룹을 캡처한 뒤 같은 패턴이 반복되는 것을 찾습니다. BRE에서는 \1, ERE에서도 동일하게 \1을 씁니다.

# 같은 두 글자가 반복되는 패턴 찾기echo -e "abcabc\nhellohello\nfoobar" | grep -E "(.{3})\1"
abcabc
hellohello

"abc"가 캡처되고, \1이 다시 "abc"를 찾습니다.

실전 예시

# /etc/passwd에서 홈 디렉토리가 /home/으로 시작하는 사용자grep -E ":/home/[^:]+:/bin/(bash|sh)$" /etc/passwd
# access.log에서 GET 또는 POST 요청만grep -E '"(GET|POST) ' /tmp/access.log
192.168.1.1 - - [24/Apr/2026:09:01:00 +0900] "GET /index.html HTTP/1.1" 200 1234
192.168.1.2 - - [24/Apr/2026:09:01:05 +0900] "POST /login HTTP/1.1" 401 512
10.0.0.5 - - [24/Apr/2026:09:01:10 +0900] "GET /api/users HTTP/1.1" 200 4096
192.168.1.1 - - [24/Apr/2026:09:01:15 +0900] "GET /admin HTTP/1.1" 403 256
10.0.0.5 - - [24/Apr/2026:09:01:30 +0900] "GET /api/items HTTP/1.1" 200 2048
192.168.1.2 - - [24/Apr/2026:09:01:35 +0900] "POST /login HTTP/1.1" 200 768
10.0.0.5 - - [24/Apr/2026:09:01:45 +0900] "GET /api/users HTTP/1.1" 500 128
# 5자리 이상 숫자가 포함된 줄 (응답 크기가 큰 요청)grep -E "[0-9]{5,}" /tmp/access.log
10.0.0.5 - - [24/Apr/2026:09:01:10 +0900] "GET /api/users HTTP/1.1" 200 4096
10.0.0.5 - - [24/Apr/2026:09:01:30 +0900] "GET /api/items HTTP/1.1" 200 2048

실무에서는 ERE(grep -E)를 더 자주 씁니다. +, ?, |, ()를 이스케이프 없이 쓸 수 있어 패턴이 읽기 쉽기 때문입니다.