{{위키데이터 속성 추적}}
[[파일:The river effect in justified text.jpg|섬네일|오른쪽|노란색 강조 부분은 다음 정규식을 사용했을 때 매치된 것이다.{{sxhl|2=ragel|1=(?<=\.) {2,}(?=[A-Z])}}]]
[[파일:Kleene.jpg|섬네일|[[스티븐 클레이니]]는 정규 표현식의 개념을 설립한 공로자이다.]]
'''정규 표현식'''(正規表現式, {{llang|en|regular expression}}, 간단히 {{lang|en|regexp}}<ref>[http://www.regular-expressions.info/tutorial.html What Regular Expressions Are Exactly - Terminology]</ref> 또는 {{lang|en|regex}}, rational expression)<ref name="Mitkov2003">{{서적 인용|author=Ruslan Mitkov|title=The Oxford Handbook of Computational Linguistics|url=https://books.google.com/books?id=yl6AnaKtVAkC&pg=PA754|year=2003|publisher=Oxford University Press|isbn=978-0-19-927634-9|page=754}}</ref><ref name="Lawson2003">{{서적 인용|author=Mark V. Lawson|title=Finite Automata|url=https://books.google.com/books?id=MDQ_K7-z2AMC&pg=PA98|date=17 September 2003|publisher=CRC Press|isbn=978-1-58488-255-8|pages=98–100}}</ref> 또는 '''정규식'''(正規式)은 특정한 규칙을 가진 문자열의 집합을 표현하는 데 사용하는 [[형식 언어]]이다. 정규 표현식은 많은 [[텍스트 편집기]]와 [[프로그래밍 언어]]에서 문자열의 검색과 치환을 위해 지원하고 있으며, 특히 [[펄]]과 [[Tcl]]은 언어 자체에 강력한 정규 표현식을 구현하고 있다.

컴퓨터 과학의 [[정규 언어]]로부터 유래하였으나 구현체에 따라서 정규 언어보다 더 넓은 언어를 표현할 수 있는 경우도 있으며, 심지어 정규 표현식 자체의 문법도 여러 가지 존재하고 있다. 현재 많은 [[프로그래밍 언어]], 텍스트 처리 프로그램, 고급 텍스트 편집기 등이 정규 표현식 기능을 제공한다. 일부는 [[펄]], [[자바스크립트]], [[루비 (프로그래밍 언어)|루비]], [[Tcl]]처럼 문법에 내장되어 있는 반면 [[닷넷 프레임워크|닷넷 언어]], [[자바 (프로그래밍 언어)|자바]], [[파이썬]], [[C POSIX 라이브러리|POSIX C]], [[C++]] ([[C++11]] 이후)에서는 [[표준 라이브러리]]를 통해 제공한다. 그 밖의 대부분의 언어들은 별도의 라이브러리를 통해 정규 표현식을 제공한다.

정규 표현식은 [[검색 엔진]], [[워드 프로세서]]와 [[문서 편집기]]의 찾아 바꾸기 대화상자, 그리고 [[sed]], [[AWK]]와 같은 문자 처리 유틸리티, [[낱말 분석|어휘 분석]]에 사용된다.

== 패턴 ==
[[파일:Thompson-kleene-star.svg|오른쪽|섬네일|[[클레이니 스타]]를 변환한 것.<br />(''s''*는 0번 이상의 ''s''를 뜻함)]]
정규 표현식이라는 문구는 일치하는 텍스트가 준수해야 하는 "패턴"을 표현하기 위해 특정한 표준의 텍스트 신택스를 의미하기 위해 사용된다. 정규 표현식의 각 문자(즉, 패턴을 기술하는 문자열 안의 각 문자)는 [[메타문자]](특별한 의미로)로 이해되거나 정규 문자('문자 그대로', 즉 '리터럴'의 의미로)로 이해된다. 이를테면 정규식 <code>a.</code> ''a''는 단지 'a'와 일치하는 리터럴 문자이며 ''.''는 새 줄을 제외한 모든 문자와 일치시키는 메타 문자이다. 그러므로 이 정규식은 이를테면 'a', 'ax', 'a0'과 일치시킬 수 있다. 더불어, 메타문자와 리터럴 문자는 주어진 패턴의 텍스트를 식별하기 위해 사용할 수 있으며, 또 수많은 인스턴스를 처리하기 위해 사용할 수도 있다. 패턴 일치는 정확히 동일한 일치에서부터 매우 포괄적인 유사 일치(메타문자에 의해 제어)에 이르기까지 다양하다. 이를테면 <code>.</code>는 매우 포괄적인 패턴이며, <code><nowiki>[a-z]</nowiki></code>('a'부터 'z'까지의 모든 문자 일치)는 덜 포괄적이며 <code>a</code>는 정확한 패턴(단지 'a'만 일치)이다. 메타문자 문법은 다양한 입력 데이터의 [[텍스트 처리]]의 자동화를 지시하는 정확하고 유연한 방법을 통해 표준 [[ASCII]] [[컴퓨터 자판|자판]]을 사용하여 입력하기 쉬운 형태로, 미리 기술된 대상을 표현하기 위해 설계되었다.

이러한 신택스를 가지는 매우 단순한 정규 표현식의 경우는 [[문서 편집기]]에서 2가지 방식으로 발음되는 동일한 단어를 위치시키는 것을 들 수 있으며, 이를테면 <code>seriali[sz]e</code>는 "serialise"와 "serialize"를 모두 일치시킨다. [[와일드카드 문자|와일드카드]] 또한 이를 성취할 수 있으나 와일드카드가 패턴화할 수 있는 것으로 국한된다. (메타문자가 더 적으며 더 단순한 언어 기반임)

[[와일드카드 문자]]를 사용하는 경우는 파일 목록에서 비슷한 이름을 [[글로브 (프로그래밍)|글로브]] 처리하는 것인 반면, 정규 표현식은 일반적으로 텍스트 문자열과 패턴 일치가 되는 애플리케이션에 보통 사용된다. 이를테면 <syntaxhighlight lang=ragel inline>^[ \t]+|[ \t]+$</syntaxhighlight>는 줄 끝이나 줄 맨앞에 여분의 공백을 일치시킨다. 어떠한 숫자라도 일치시키기 위해 쓰이는 진보한 정규 표현식은 <syntaxhighlight lang=ragel inline>[+-]?(\d+(\.\d+)?|\.\d+)([eE][+-]?\d+)?</syntaxhighlight>이다. 더 많은 예를 보려면 [[#예|예]] 문단을 참고할 것.

== 역사 ==
정규 표현식은 1951년 수학자 [[스티븐 클레이니]]가 정규 이벤트(regular event)라는 수학적 표기법을 사용하여 [[정규 언어]]를 설명하면서 시작되었다.<ref name = "Leung, New Mexico State University, 2010" >{{웹 인용| url=https://www.cs.nmsu.edu/historical-projects/Projects/kleene.9.16.10.pdf | title=Regular Languages and Finite Automata | access-date=13 August 2019 | first=Hing | last=Leung | date=16 September 2010 | website=[[뉴멕시코 주립 대학교|New Mexico State University]] | quote=The concept of regular events was introduced by Kleene via the definition of regular expressions. | archive-url=https://web.archive.org/web/20131205193130/https://www.cs.nmsu.edu/historical-projects/Projects/kleene.9.16.10.pdf | archive-date=5 December 2013 | df=dmy-all }}</ref> 이는 [[이론 컴퓨터 과학]], [[오토마타 이론]](계산 모델)의 하위 분야, [[형식 언어]]의 설명 및 분류에서 나타났다. [[패턴 매칭]]의 다른 초기 구현에는 정규 표현식을 사용하지 않고 대신 자체 패턴 일치 구성을 사용하는 [[SNOBOL]] 언어가 포함된다.

정규 표현식은 1968년부터 텍스트 편집기의 패턴 매칭과 컴파일러의 어휘 분석이라는 두 가지 용도로 널리 사용되었다. 프로그램 형식에서 정규 표현식이 처음 등장한 것은 [[켄 톰프슨]]이 [[텍스트 파일]]의 패턴을 일치시키는 수단으로 클레이니의 표기법을 QED 편집기에 내장했을 때였다. 속도를 위해 톰프슨은 [[JIT 컴파일]]의 중요한 초기 예인 [[호환 시분할 시스템]]의 IBM 7094 코드에 JIT 컴파일을 통해 정규 표현식 일치를 구현했다. 그는 나중에 이 기능을 유닉스 편집기 [[Ed (문서 편집기)|ed]]에 추가했고, 이로 인해 결국 인기 있는 검색 도구인 [[grep]]에서 정규 표현식을 사용하게 되었다("grep"은 ed 편집기에서 정규 표현식 검색을 위한 명령에서 파생된 단어이다: "정규 표현식에 대한 전역 검색 및 일치하는 줄 출력"을 뜻하는 g/re/p). 톰프슨이 QED를 개발한 것과 거의 같은 시기에 [[더글러스 T. 로스]](Douglas T. Ross)를 포함한 연구자 그룹은 컴파일러 설계의 어휘 분석에 사용되는 정규 표현식 기반 도구를 구현했다.

[[vi]], [[lex]], [[Sed (유틸리티)|sed]], [[AWK]] 및 [[expr]]을 포함하여 1970년대 [[벨 연구소]]의 유닉스 프로그램과 [[이맥스]](자체적으로 호환되지 않는 구문 및 동작을 가지고 있음)와 같은 다른 프로그램에서 이러한 원래 형태의 정규 표현식의 다양한 변형이 사용되었다. 정규 표현식은 이후 다양한 프로그램에서 채택되었으며 이러한 초기 형식은 1992년 POSIX.2 표준으로 표준화되었다.

1980년대에는 [[펄]]에서 더 복잡한 정규 표현식이 등장했는데, 이는 원래 [[헨리 스펜서]](1986)가 작성한 정규 표현식 라이브러리에서 파생되었으며 나중에 고급 정규 표현식(Advanced Regular Expressions)이라고 불리는 [[Tcl]]에 대한 구현을 작성했다. Tcl 라이브러리는 향상된 성능 특성을 갖춘 하이브리드 [[비결정론적 유한 상태 기계|NFA]]/[[결정론적 유한 상태 기계|DFA]] 구현이다. 스펜서의 Tcl 정규 표현식 구현을 채택한 소프트웨어 프로젝트에는 [[PostgreSQL]]이 포함된다. 펄은 나중에 스펜서의 원래 라이브러리를 확장하여 많은 새로운 기능을 추가했다. [[라쿠 (프로그래밍 언어)|라쿠]](구 명칭: 펄 6) 설계 노력의 일부는 펄의 정규 표현식 통합을 개선하고 구문 분석 표현식 문법 정의를 허용하도록 범위와 기능을 늘리는 것이다. 그 결과 라쿠 문법을 정의하고 해당 언어의 프로그래머에게 도구를 제공하는 데 사용되는 라쿠 규칙이라는 미니 언어가 탄생했다. 이러한 규칙은 펄 5.x 정규 표현식의 기존 기능을 유지하지만 하위 규칙을 통해 재귀 하강 파서의 [[배커스-나우르 표기법|BNF]] 스타일 정의도 허용한다.

문서 및 데이터베이스 모델링을 위한 구조화된 정보 표준에서 정규 표현식 사용은 1960년대에 시작되어 ISO SGML(ANSI "GCA 101-1983"에서 이전)과 같은 산업 표준이 통합된 1980년대에 확장되었다. 구조 사양 언어 표준의 커널은 정규 표현식으로 구성된다. 이러한 사용은 [[문서 형식 정의|DTD]] 요소 그룹 구문에서 분명하게 나타난다. 정규 표현식을 사용하기 전에는 많은 검색 언어에서 간단한 와일드카드를 허용했다. 예를 들어 임의의 문자 시퀀스와 일치하는 "*" 및 "?" 단일 문자와 일치한다. 이에 대한 유물은 오늘날 파일 이름에 대한 [[글로브 (프로그래밍)|글로브]] 구문과 [[SQL]] LIKE 연산자에서 찾을 수 있다.

1997년부터 [[필립 하젤]]은 펄의 정규 표현식 기능을 밀접하게 모방하려고 시도하고 [[PHP]] 및 [[아파치 HTTP 서버]]를 포함한 많은 최신 도구에서 사용되는 PCRE([[펄 호환 정규 표현식]])를 개발했다.

오늘날 정규 표현식은 프로그래밍 언어, 텍스트 처리 프로그램(특히 [[낱말 분석|어휘 분석기]]), 고급 텍스트 편집기 및 기타 프로그램에서 널리 지원된다. 정규 표현식 지원은 [[자바 (프로그래밍 언어)|자바]] 및 [[파이썬]]을 포함한 많은 프로그래밍 언어의 표준 라이브러리의 일부이며 펄 및 [[ECMA스크립트]]를 포함한 다른 프로그래밍 언어의 구문에 내장되어 있다. 2010년대 후반에 몇몇 회사에서는 [[중앙 처리 장치|CPU]] 구현에 비해 더 빠른 PCRE 호환 정규 표현식 엔진의 하드웨어, [[FPGA]], [[그래픽 처리 장치|GPU]] 구현을 제공하기 시작했다.

== 기본 개념 ==
주로 '''패턴'''(pattern)으로 부르는 정규 표현식은 특정 목적을 위해 필요한 문자열 집합을 지정하기 위해 쓰이는 식이다. 문자열의 유한 집합을 지정하는 단순한 방법은 문자열의 [[데이터 요소|요소]]나 멤버를 나열하는 것이다. 그러나 문자열의 원하는 집합을 지정하기 위해 사용할 수 있는 더 간결한 방법들이 있다. 이를테면 3개의 문자열 "Handel", "Händel", "Haendel"을 포함하는 집합은 패턴 <code>H(ä|ae?)ndel</code>으로 지정이 가능하며 이러한 패턴은 3개의 문자열을 각각 '''일치'''(match)시킨다고 이야기한다.

; 불리언 "또는"
: [[수직선 (기호)|수직선]]은 여러 항목 중 선택을 하기 위해 구분한다. 이를테면 <code>gray|grey</code>는 "gray" 또는 "grey"와 일치한다.

; 그룹 묶기
: [[괄호]]를 사용하면 [[연산자 (프로그래밍)|연산자]]의 범위와 우선권을 정의할 수 있다. 이를테면 <code>gray|grey</code>와 <code>gr(a|e)y</code>는 "gray"나 "grey" 집합을 둘 다 기술하는 동일 패턴이다.

; 양의 지정
:{|
| style="width:15px; vertical-align:top;" | <code>'''?'''</code>
|물음표는 0번 또는 1차례까지의 발생을 의미한다. 이를테면 <code>colou?r</code>는 "color"와 "colour"를 둘 다 일치시킨다.
|-
| style="vertical-align:top;" | <code>'''<nowiki>*</nowiki>'''</code>
|별표는 0번 이상의 발생을 의미한다. 이를테면 <code>ab*c</code>는 "ac", "abc", "abbc", "abbbc" 등을 일치시킨다.
|-
| style="vertical-align:top;" | <code>'''+'''</code>
|덧셈 기호는 1번 이상의 발생을 의미한다. 이를테면 <code>ab+c</code>는 "abc", "abbc", "abbbc" 등을 일치시키지만 "ac"는 일치시키지 않는다.
|-
|<code>'''{n}'''</code><ref name="grep">grep(1) man page</ref>
|정확히 n 번만큼 일치시킨다.
|-
|<code>'''{min,}'''</code><ref name="grep"/>
|"min"번 이상만큼 일치시킨다.
|-
|<code>'''{min,max}'''</code><ref name="grep"/>
|적어도 "min"번만큼 일치시키지만 "max"번을 초과하여 일치시키지는 않는다.
|}

== 문법 ==
정규 표현식의 패턴은 대상 문자열과 일치시킨다. 이 패턴은 일련의 원자로 구성된다. 하나의 원자는 정규 표현식 패턴 안의 하나의 점이며, 대상 문자열과 일치시키기 위해 존재한다. 가장 단순한 형태의 원자는 리터럴(literal)이지만 원자를 일치시키기 위해 패턴을 묶을 때에는 메타문자로서 <code>( )</code>를 사용해야 한다. 메타문자는 원자 외에도 얼마나 많은 원자가 있는지를 가리키는 수량자(quantifier), 선택적인 대안을 가리키는 논리적 OR 문자, 그리고 원자의 존재를 부정하는 NOT 문자, 그리고 전에 일치된 원자를 참조할 수 있게 하는 역참조(backreference)를 만드는 것을 도와준다.
=== 구분 문자 ===
프로그래밍 언어에서 정규 표현식을 입력할 때, 통상적인 문자열 리터럴로 표현할 수 있으므로 일반적으로 인용 부호로 처리된다. 이는 이를테면 C, 자바, 파이썬에서도 동일한데, 정규표현식 <code>re</code>는 <code>"re"</code>로 입력된다. 그러나 [[구분 문자]]로 슬래시를 사용하는 경우도 있는데 정규 표현식 <code>re</code>에 대해서 <code>/re/</code>를 사용하는 식이다. 이는 ed라는 편집기에서 기원하며, <code>/</code>는 검색을 위한 편집기 명령어이고, <code>/re/</code>라는 식은 특정한 범위의 줄들을 지정하는데 사용할 수 있다. 비슷한 방식이 [[sed]]에서 사용되는데, 검색 후 치환은 <code>s/re/replacement/</code>를 사용하며 패턴은 <code>/re1/,/re2/</code>처럼 특정한 범위의 줄을 지정하여 쉼표(,)로 결합할 수 있다. 이러한 표기법은 특히 [[펄]]에서도 사용된다.
=== 표준 ===
==== POSIX 기본 및 확장 표준 문법 ====
문자 클래스, "["와 "]" 사이에 포함된 문자 집합 외부에서는 12개의 문자가, 내부에서는 오직 4개의 문자("{{lang|en|\}}", "^", "-", "]", [[자바 (프로그래밍 언어)|자바]]와 [[닷넷 프레임워크|닷넷]]은 "["를 포함)만 특수문자를 의미한다.<ref>잰 고이바에르츠, 스티븐 리바이선 저 김지원 역, 《한 권으로 끝내는 정규표현식》, 한빛미디어(주), 2010, 53쪽</ref> 아래는 POSIX 기본 및 확장 표준의 문법이다.

{| style = "margin-left:1em;margin-right:0; font-size:95%" class="wikitable" width="900px"
|+
! width=10%| 메타문자
! width=20%| 기능
! width=60%| 설명
|-
|align=center| .
| 문자 || 1개의 문자와 일치한다. 단일행 모드에서는 [[새줄 문자]]를 제외한다.
|-
|align=center| [ ]
| 문자 클래스 || "["과 "]" 사이의 문자 중 하나를 선택한다. "¦"를 여러 개 쓴 것과 같은 의미이다. 예를 들면 [abc]d는 ad, bd, cd를 뜻한다. 또한, "-" 기호와 함께 쓰면 범위를 지정할 수 있다. "[a-z]"는 a부터 z까지 중 하나, "[1-9]"는 1부터 9까지 중의 하나를 의미한다.
|-
|align=center| [^ ]
| 부정 || 문자 클래스 안의 문자를 제외한 나머지를 선택한다. 예를 들면 [^abc]d는 ad, bd, cd는 포함하지 않고 ed, fd 등을 포함한다. [^a-z]는 알파벳 소문자로 시작하지 않는 모든 문자를 의미한다.
|-
|align=center| ^
| 처음 || 문자열이나 행의 처음을 의미한다.
|-
|align=center| $
| 끝 || 문자열이나 행의 끝을 의미한다.
|-
|align=center| ( )
| 하위식 || 여러 식을 하나로 묶을 수 있다. "abc¦adc"와 "a(b¦d)c"는 같은 의미를 가진다.
|-
|align=center| \n
| 일치하는 n번째 패턴 || 일치하는 패턴들 중 n번째를 선택하며, 여기에서 n은 1에서 9 중 하나가 올 수 있다.
|-
|align=center| *
| 0회 이상 || 0개 이상의 문자를 포함한다. "a*b"는 "b", "ab", "aab", "aaab"를 포함한다.
|-
|align=center| {m, n}
| m회 이상 n회 이하 || "a{1,3}b"는 "ab", "aab", "aaab"를 포함하지만, "b"나 "aaaab"는 포함하지 않는다.
|-
|}

많은 [[프로그래밍 언어]]에서는 이를 확장한 문법을 가지고 있다. 이 중 POSIX에서 사용되는 확장 문법은 [[#POSIX 확장 문법|POSIX 확장 문법]]을 참고할 것. 그 외의 환경에 대해서는 [[#문자 클래스|문자 클래스]] 단락을 참고할 것.

==== POSIX 확장 문법 ====
{| style = "margin-left:1em;margin-right:0; font-size:95%" class="wikitable" width="900px"
|+
! width=10%| 메타문자
! width=20%| 기능
! width=60%| 설명
|-
|align=center| ?
| 0 또는 1회 ||  "a?b"는 "b", "ab"를 포함한다.
|-
|align=center| +
| 1회 이상 || "a+b"는 "ab", "aab", "aaab"를 포함하지만 "b"는 포함하지 않는다.
|-
|align=center| ¦
| 선택 || 여러 식 중에서 하나를 선택한다. 예를 들어, "abc¦adc"는 abc와 adc 문자열을 모두 포함한다.
|-
|}

==== 문자 클래스 ====
문자 클래스는 문자열 일치 다음으로 가장 기본적인 정규 표현식 개념이다. 이는 하나의 작은 일련의 문자열들을 더 큰 집합의 문자열들과 일치시키도록 한다. 이를테면, <code>[A-Z]</code>는 알파벳을 대표하며 <code>\d</code>는 임의의 숫자를 의미할 수 있다. 문자 클래스는 POSIX 수준에 적용한다.

<code>[a-Z]</code>와 같은 특정 범위의 문자들을 지정할 때 컴퓨터의 로캘 설정들은 문자 인코딩의 수치적 나열에 따라 내용을 결정한다. 그러한 나열에 따라 수치들을 저장할 수 있으며 그 순서는 ''abc...zABC...Z'', ''aAbBcC...zZ''와 같이 될 수 있다. 그러므로 POSIX 표준은 문자 클래스를 정의하며 이는 설치된 정규 표현식 처리기가 인지한다. 이러한 정의들은 다음의 표를 따른다:

{| class="wikitable"
|-
! POSIX !! 비표준 !! 펄/Tcl !! Vim !! ASCII !! 설명
|-
| <code>[:alnum:]</code>
|
|
|
| <code>[A-Za-z0-9]</code>
| 영숫자
|-
|
| <code>[:word:]</code>
| <code>\w</code>
| <code>\w</code>
| <code>[A-Za-z0-9_]</code>
| 영숫자 + "_"
|-
|
|
| <code>\W</code>
| <code>\W</code>
| <code>[^A-Za-z0-9_]</code>
| 낱말이 아닌 문자
|-
| <code>[:alpha:]</code>
|
|
| <code>\a</code>
| <code>[A-Za-z]</code>
| 알파벳 문자
|-
| <code>[:blank:]</code>
|
|
| <code>\s</code>
| <code>[ [[\t]]]</code>
| 공백과 탭
|-
|
|
| <code>\b</code>
| <code>\&lt; \&gt;</code>
| <code>(?<=\W)(?=\w)&#124;(?<=\w)(?=\W)</code>
| 낱말 경계
|-
| <code>[:cntrl:]</code>
|
|
|
| <code>[\x00-\x1F\x7F]</code>
| [[제어 문자]]
|-
| <code>[:digit:]</code>
|
| <code>\d</code>
| <code>\d</code>
| <code>[0-9]</code>
| 숫자
|-
|
|
| <code>\D</code>
| <code>\D</code>
| <code>[^0-9]</code>
| 숫자가 아닌 문자
|-
| <code>[:graph:]</code>
|
|
|
| <code>[\x21-\x7E]</code>
| 보이는 문자
|-
| <code>[:lower:]</code>
|
|
| <code>\l</code>
| <code>[a-z]</code>
| 소문자
|-
| <code>[:print:]</code>
|
|
| <code>\p</code>
| <code>[\x20-\x7E]</code>
| 보이는 문자 및 공백 문자
|-
| <code>[:punct:]</code>
|
|
|
| <code><nowiki>[][!"#$%&'()*+,./:;<=>?@\^_`{|}~-]</nowiki></code>
| 구두점
|-
| <code>[:space:]</code>
|
| <code>\s</code>
| <code>\_s</code> <small>(단순히 줄 끝에 추가)</small>
| <code>[ [[\t]][[\r]][[\n]][[\v]][[\f]]]</code>
| [[공백 문자]]
|-
|
|
| <code>\S</code>
|
| <code>[^ \t\r\n\v\f]</code>
| 공백이 아닌 모든 문자
|-
| <code>[:upper:]</code>
|
|
| <code>\u</code>
| <code>[A-Z]</code>
| 대문자
|-
| <code>[:xdigit:]</code>
|
|
| <code>\x</code>
| <code>[A-Fa-f0-9]</code>
| 16진수
|}

=== 펄과 PCRE ===
{{참고|펄 호환 정규 표현식}}
표현력과 (상대적으로) 양호한 가독성으로 인해 [[자바 (프로그래밍 언어)|자바]], [[자바스크립트]], [[파이썬]], [[루비 (프로그래밍 언어)|루비]], [[마이크로소프트]]의 [[닷넷 프레임워크]], [[XML 스키마]] 등의 여러 수많은 유틸리티들과 프로그래밍 언어들은 펄의 정규식과 비슷한 문법을 채택하고 있다. [[Boost]]와 [[PHP]]와 같은 일부 언어들과 도구들은 여러 방식의 정규식을 지원한다. 펄 파생 정규식 구현체들은 완전히 동일한 것은 아니며 일반적으로 1994년에 출시된 펄 5.0의 기능의 하위 집합을 구현하고 있다. 펄은 종종 다른 언어에서 발견되는 기능들을 도입하고 있는데, 이를테면 펄 5.10은 [[펄 호환 정규 표현식|PCRE]]와 파이썬에서 개발되는 문법 확장들을 구현한다.<ref>{{웹 인용 | url=http://perldoc.perl.org/perlre.html#PCRE%2fPython-Support | title= Perl Regular Expression Documentation |publisher=perldoc.perl.org | accessdate=January 8, 2012}}</ref>

== 이용 ==
정규 표현식은 다양한 [[텍스트 처리]] 작업, 더 일반적으로 문자열 처리에 유용하며, 여기에서 데이터는 반드시 텍스트일 필요는 없다. 일반적으로 [[데이터 검증]], [[데이터 스크래핑]](일반적으로 [[웹 스크래핑]]), [[데이터 랭글링]], 단순 [[구문 분석|파싱]], [[문법 강조]] 시스템 개발 등의 작업에 응용된다.

정규 표현식이 인터넷 [[검색 엔진]]에 유용할 수 있으나 전체 데이터베이스를 거쳐 이것들을 처리하기에는 정규 표현식의 복잡도와 설계에 따라 컴퓨터 자원을 과도하게 소비할 수 있다. 대개의 경우 시스템 관리자들이 정규 표현식 기반 쿼리를 내부적으로 수행할 수 있지만 대부분의 검색 엔진들은 대중에게 정규 표현식 지원을 제공하지 않는다.

== 예 ==
특정 문법 규칙은 사용 중인 특정 구현체, [[프로그래밍 언어]], [[라이브러리 (컴퓨팅)|라이브러리]]에 따라 다양하다. 또한 정규 표현식 구현체들의 기능은 [[소프트웨어 버전]] 간에도 다를 수 있다.

정규 표현식들은 예제 없이 설명과 이해를 동시에 하는 것은 어려울 수 있다. 아래에는 정규 표현식의 속성 중 일부의 기본적인 설명을 제시한다.

아래의 항목들은 예제에 사용된다.<ref name="clarify000">The character 'm' is not always required to specify a [[펄|Perl]] match operation. For example, <code>m/[^abc]/</code> could also be rendered as <code>/[^abc]/</code>. The 'm' is only necessary if the user wishes to specify a match operation without using a forward-slash as the regex [[구분 문자|delimiter]]. Sometimes it is useful to specify an alternate regex delimiter in order to avoid "[[구분 문자 충돌|delimiter collision]]". See '[http://perldoc.perl.org/perlre.html perldoc perlre]' for more details.</ref>

   메타문자 ;; 메타문자들의 열은 표현할 정규식을 지정한다.
    =~ m//          ;; 펄에서 문자열을 '일치'시키려는 동작을 지정한다.
    =~ s///         ;; 펄에서 문자열을 '대체'시키려는 동작을 지정한다.

이 예제들에 사용된 문법과 규칙들은 다른 프로그래밍 환경에서와 일치한다.<ref>e.g., see ''[[자바 (프로그래밍 언어)|자바]] [[오라일리 미디어|in a Nutshell]]''&nbsp;— Page 213, ''[[파이썬]] Scripting for Computational Science''&nbsp;— Page 320, Programming [[PHP]]&nbsp;— Page 106</ref>

{| class="wikitable"
! 메타문자
! 설명
! 예시<ref>모든 if문은 true(참)을 반환한다</ref>
|-
! <code>.</code>
| 일반적으로 새 줄을 제외한 모든 어떠한 문자열과도 일치한다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/...../) {
  print "$string1 has length >= 5\n";
}
</syntaxhighlight>'''출력:'''
<pre>
Hello World
 has length >= 5
</pre>
|-
! <code>( )</code>
| 일련의 패턴 요소들을 하나의 요소로 묶는다. <br/>괄호 안의 패턴을 일치시킬 때 <code>$1</code>, <code>$2</code>, ... 중 하나를 사용할 수 있다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/(H..).(o..)/) {
  print "We matched '$1' and '$2'\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
We matched 'Hel' and 'o W'
</syntaxhighlight>
|-
! <code>+</code>
| 1번 이상 발생하는 패턴과 일치시킨다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/l+/) {
  print "There are one or more consecutive letter \"l\"'s in $string1\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
There are one or more consecutive letter "l"'s in Hello World
</syntaxhighlight>
|-
! <code>?</code>
| 0~1번 발생하는 패턴과 일치시킨다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/H.?e/) {
  print "There is an 'H' and a 'e' separated by ";
  print "0-1 characters (Ex: He Hoe)\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
There is an 'H' and a 'e' separated by 0-1 characters (Ex: He Hoe)
</syntaxhighlight>
|-
! <code>?</code>
| <!--Modifies the <code>*</code>, <code>+</code>, <code>?</code> or <code>{M,N}</code>'d regex that comes before to match as few times as possible.-->
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/(l.+?o)/) {
  print "The non-greedy match with 'l' followed by one or\n";
  print "more characters is 'llo' rather than 'llo Wo'.\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
The non-greedy match with 'l' followed by one or
more characters is 'llo' rather than 'llo Wo'.
</syntaxhighlight>
|-
! <code>*</code>
| 0번 이상 발생하는 패턴과 일치시킨다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/el*o/) {
  print "There is an 'e' followed by zero to many ";
  print "'l' followed by 'o' (eo, elo, ello, elllo)\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
There is an 'e' followed by zero to many 'l' followed by 'o' (eo, elo, ello, elllo)
</syntaxhighlight>
|-
! {M,N}
| 최소 M번, 최대 N번 발생되는 패턴과 일치시킨다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/l{1,2}/) {
 print "There exists a substring with at least 1 ";

 print "and at most 2 l's in $string1\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
There exists a substring with at least 1 and at most 2 l's in Hello World
</syntaxhighlight>
|-
! <code>[...]</code>
| 가능한 문자열의 집합과 일치시킨다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/[aeiou]+/) {
  print "$string1 contains one or more vowels.\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
Hello World
 contains one or more vowels.
</syntaxhighlight>
|-
! <code><nowiki>|</nowiki></code>
| 가능성 있는 항목들을 구별하여 선택한다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/(Hello|Hi|Pogo)/) {
  print "At least one of Hello, Hi, or Pogo is ";
  print "contained in $string1.\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
At least one of Hello, Hi, or Pogo is contained in Hello World
.
</syntaxhighlight>
|-
! <code>\b</code>
| <!--Matches a zero-width boundary between a word-class character (see next) and either a non-word class character or an edge.-->
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/llo\b/) {
  print "There is a word that ends with 'llo'\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
There is a word that ends with 'llo'
</syntaxhighlight>
|-
! <code>\w</code>
| "_"를 포함한 영숫자를 일치시킨다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/\w/) {
  print "There is at least one alphanumeric ";
  print "character in $string1 (A-Z, a-z, 0-9, _)\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
There is at least one alphanumeric character in Hello World
 (A-Z, a-z, 0-9, _)
</syntaxhighlight>
|-
! <code>\W</code>
| "_"를 제외하여 영숫자가 아닌 문자열들과 일치시킨다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/\W/) {
  print "The space between Hello and ";
  print "World is not alphanumeric\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
The space between Hello and World is not alphanumeric
</syntaxhighlight>
|-
! <code>\s</code>
| 공백 문자와 일치시킨다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/\s.*\s/) {
  print "There are TWO whitespace characters, which may";
  print " be separated by other characters, in $string1";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
There are TWO whitespace characters, which may be separated by other characters, in Hello World
</syntaxhighlight>
|-
! <code>\S</code>
| 공백을 제외한 어떠한 것이든 일치시킨다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/\S.*\S/) {
  print "There are TWO non-whitespace characters, which";
  print " may be separated by other characters, in $string1";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
There are TWO non-whitespace characters, which may be separated by other characters, in Hello World
</syntaxhighlight>
|-
! <code>\d</code>
| 숫자를 일치시킨다.
|  <syntaxhighlight lang="perl">
$string1 = "99 bottles of beer on the wall.";
if ($string1 =~ m/(\d+)/) {
  print "$1 is the first number in '$string1'\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
99 is the first number in '99 bottles of beer on the wall.'
</syntaxhighlight>
|-
! <code>\D</code>
| 숫자가 아닌 항목을 일치시킨다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/\D/) {
  print "There is at least one character in $string1";
  print " that is not a digit.\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
There is at least one character in Hello World
 that is not a digit.
</syntaxhighlight>
|-
! <code>^</code>
| 줄이나 문자열의 시작점과 일치시킨다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/^He/) {
  print "$string1 starts with the characters 'He'\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
Hello World
 starts with the characters 'He'
</syntaxhighlight>
|-
! <code>$</code>
| 줄이나 문자열의 끝과 일치시킨다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/rld$/) {
  print "$string1 is a line or string ";
  print "that ends with 'rld'\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
Hello World
 is a line or string that ends with 'rld'
</syntaxhighlight>
|-
! <code>\A</code>
| 문자열의 시작점과 일치시킨다. (내부 줄이 아닌)
|  <syntaxhighlight lang="perl">
$string1 = "Hello\nWorld\n";
if ($string1 =~ m/\AH/) {
  print "$string1 is a string ";
  print "that starts with 'H'\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
Hello
World
 is a string that starts with 'H'
</syntaxhighlight>
|-
! <code>\z</code>
| 문자열의 끝과 일치시킨다. (내부 줄이 아닌)<ref name='Perl Best Practices'>{{서적 인용| last = Conway | first = Damian | authorlink = 데이미언 콘웨이 | title = Perl Best Practices | chapter = Regular Expressions, End of String | publisher = [[오라일리 미디어|O'Reilly]] | pages = 240 | url = http://www.scribd.com/doc/15491004/Perl-Best-Practices | year=2005 | isbn = 978-0-596-00173-5}}</ref>
|  <syntaxhighlight lang="perl">
$string1 = "Hello\nWorld\n";
if ($string1 =~ m/d\n\z/) {
  print "$string1 is a string ";
  print "that ends with 'd\\n'\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
Hello
World
 is a string that ends with 'd\n'
</syntaxhighlight>
|-
! <code>[^...]</code>
| 괄호 안의 항목을 제외한 모든 문자열과 일치시킨다.
|  <syntaxhighlight lang="perl">
$string1 = "Hello World\n";
if ($string1 =~ m/[^abc]/) {
  print "$string1 contains a character other than ";
  print "a, b, and c\n";
}
</syntaxhighlight>'''출력:'''<syntaxhighlight lang="text">
Hello World
 contains a character other than a, b, and c
</syntaxhighlight>
|}

== 같이 보기 ==
* [[정규 언어]]
* [[정규 문법]]
* [[제어 문자]]

== 각주 ==
{{각주}}

== 외부 링크 ==
* {{위키공용분류-줄}}
* {{dmoz|Computers/Programming/Languages/Regular_Expressions|정규 표현식}}
* {{언어링크|en}} ISO/IEC 9945-2:1993 [https://web.archive.org/web/20151107053308/http://www.iso.org/iso/catalogue_detail.htm?csnumber=17841 ''Information technology – Portable Operating System Interface (POSIX) – Part 2: Shell and Utilities'']
* {{언어링크|en}} ISO/IEC 9945-2:2002 [https://web.archive.org/web/20151107053309/http://www.iso.org/iso/iso_catalogue/catalogue_ics/catalogue_detail_ics.htm?csnumber=37313 ''Information technology – Portable Operating System Interface (POSIX) – Part 2: System Interfaces'']
* {{언어링크|en}} ISO/IEC 9945-2:2003 [https://web.archive.org/web/20151107053310/http://www.iso.org/iso/iso_catalogue/catalogue_ics/catalogue_detail_ics.htm?csnumber=38790 ''Information technology – Portable Operating System Interface (POSIX) – Part 2: System Interfaces'']
* {{언어링크|en}} ISO/IEC/IEEE 9945:2009 [https://web.archive.org/web/20151107053310/http://www.iso.org/iso/iso_catalogue/catalogue_ics/catalogue_detail_ics.htm?csnumber=50516 ''Information technology – Portable Operating System Interface (POSIX®) Base Specifications, Issue 7'']

{{형식 언어 및 형식 문법}}
{{전거 통제}}

[[분류:1951년 도입]]
[[분류:코드 예시에 관한 문서]]
[[분류:오토마타 이론]]
[[분류:형식 언어]]
[[분류:패턴 매칭]]
[[분류:프로그래밍 구성체]]