정규식은 실제로 어떻게 작동합니까?


30

에세이가 쓰여진 문서를 가지고 있다고 가정하십시오. 이 에세이를 구문 분석하여 특정 단어 만 선택하려고합니다. 시원한.

정규식을 사용하면 파일을 한 줄씩 파싱하고 단어별로 일치하는 것을 찾는 것보다 빠릅니다. 그렇다면 어떻게 작동합니까? 각 단어를 보는 것보다 어떻게 빨리 갈 수 있습니까?


5
정규 표현식이 더 빠를 것이라고 생각하지만 (제로 증거를 암시하지 않음) 왜 그런지 알지 못합니까? 아마도 당신의 가정을 재고해야 할 것입니다.
pdr

3
따라서 가정. 내가 증거를 가지고 있다면, 그렇지 않습니까?
lazeR

4
요점은 그것이 아니다. 요점은 당신을 그 가정으로 이끌었습니다. 당신은 당신의 질문에 대한 증거가 필요하지 않지만, 당신의 가정에 대한 추론이 필요합니다.
yannis

1
err, 입력 문자열의 모든 문자가 상태 머신을 다음 상태로 이동시키는 것은 아닙니다. 나는 누군가가 어떻게 그 작업을 느리게 할 수 있는지
모르겠다

2
나는 더 빨리 확신 할 수 없지만 정규 표현식을 사용하는 주된 이유는 복잡한 매칭 패턴의 우아함으로 인해 코딩 환경에서 더 잘 표현할 수있는 방법을 찾지 못할 것입니다.
Mantorok

답변:


47

어떻게 작동합니까?

오토마타 이론을 살펴보세요

간단히 말해서, 각 정규 표현식은 동등한 유한 오토 마톤을 가지며 유한 오토 마톤으로 컴파일되고 최적화 될 수 있습니다. 관련된 알고리즘은 많은 컴파일러 서적에서 찾을 수 있습니다. 이 알고리즘은 awk 및 grep과 같은 유닉스 프로그램에서 사용됩니다.

그러나 대부분의 최신 프로그래밍 언어 (Perl, Python, Ruby, Java (및 JVM 기반 언어), C #)는이 방법을 사용하지 않습니다. 그들은 정규식을 트리 또는 정규식의 다양한 하위 청크를 나타내는 일련의 구성으로 컴파일하는 재귀 역 추적 접근법을 사용합니다. 대부분의 최신 "정규 표현식"구문은 정규 언어 그룹 외부에있는 역 참조를 제공하며 (이것은 유한 오토마타로 표현되지 않음) 재귀 역 추적 방식으로 간단하게 구현할 수 있습니다.

최적화는 일반적으로보다 효율적인 상태 머신을 생성합니다. 예를 들어 : aaaab | aaaac | aaaad를 고려하면 일반 프로그래머는 10 분 안에 간단하지만 덜 효율적인 검색 구현 (세 개의 문자열을 개별적으로 비교)을 얻을 수 있습니다. 그러나 aaaa [bcd]와 동일하다는 것을 인식하면 처음 네 개의 'a'를 검색하여 [b, c, d]에 대해 다섯 번째 문자를 테스트하면 더 나은 검색을 수행 할 수 있습니다. 최적화 과정은 수년 전에 필자의 컴파일러 작업 중 하나 였으므로 대부분의 현대 정규식 엔진에도 있다고 가정합니다.

반면, 상태 머신은 "사소한 구현"에 비해 더 많은 공간을 사용하기 때문에 문자열을 받아 들일 때 이점이 있습니다. SQL 문자열에서 인용을 이스케이프 제거하는 프로그램을 고려하십시오. 즉, 1) 작은 따옴표로 시작하고 끝납니다. 2) 작은 따옴표는 두 개의 연속적인 작은 따옴표로 이스케이프됩니다. 따라서 입력 [ 'a' '']는 출력 [a ']를 산출해야합니다. 상태 머신을 사용하면 연속적인 작은 따옴표는 두 가지 상태로 처리됩니다. 이 두 상태는 다음과 같이 각 입력 문자가 정확히 한 번만 처리되도록 입력 기록을 기억하는 목적으로 사용됩니다.

...
S1->'->S2
S1->*->S1, output *, * can be any other character 
S2->'->S1, output '
S2->*->END, end the current string

따라서 제 생각에는 정규 표현식이 사소한 경우에는 느리지 만 일반적으로 사람이 최적화를 안정적으로 수행 할 수 없다는 사실을 고려할 때 수동으로 만들어진 검색 알고리즘보다 빠릅니다.

문자열 검색과 같은 사소한 경우에도 스마트 엔진은 상태 맵의 단일 경로를 인식하고 해당 부분을 간단한 문자열 비교로 줄이고 상태 관리를 피할 수 있습니다.

프레임 워크 / 라이브러리의 특정 엔진은 엔진이 프로그래머가 일반적으로 필요하지 않은 많은 다른 작업을 수행하기 때문에 느려질 수 있습니다. 예 : .NET의 Regex 클래스는 일치, 그룹 및 캡처를 포함하여 많은 개체를 만듭니다.


2
나는 그것을 나 자신에게 더 잘 말할 수 없었다. 내가 추가 할 유일한 것은 : 정규 표현식은 게으른 프로그래머를 보완 할 수도 있습니다 . 이 예에서는 aaaab|aaaac|aaaadvs. 를 언급했습니다 aaaa[bcd]. 두 가지가 수학적으로 동등하고 동일한 DFA를 생성하므로 프로그래머가 이해하기 쉬운 방식으로 정규 표현식을 표현할 수있는 자유를 더 많이 부여 할 필요가 있습니다. ..
riwalk

고마워, 이것은 내가 선택한 오토마타 수업 덕분에 실제로 의미가있다
lazeR

이것은 정규식이 과잉 인 사소한 문제의 예입니까? : stackoverflow.com/questions/18955099/…
Menelaos Bakopoulos

17

컴퓨터가 빠르기 때문에 정규 표현식이 빠르게 보입니다.

1980 년대에 1 MIPS가 빠른 컴퓨터였던 정규식은 느리고 추악하고 계산 집약적이기 때문에 걱정, 관심사 및 연구의 상당히 큰 영역이었습니다. 영리한 알고리즘 개발이 따르고 도움이되었지만 요즘 모든 실제적인 목적을 위해 금이 간 기계가 기적을 기록하는 기적을보고 있습니다.


2
단일 단어를 찾고 있다면 두 방법이 동일합니다 (또는 정규 표현식이 약간 느립니다). 그러나 복잡한 표현 (및 합리적인 크기의 텍스트)이 주어지면 정규 표현식은 단순한 검색보다 빠를 것입니다 (간단한 검색을 간단하게 작성한다고 가정하면 (빠른 복잡한 검색을 항상 작성할 수 있음)). 날씨가 중요한 것은 너무 일반적인 질문이므로 사례별로 살펴 봐야합니다.
Martin York

3
-1. 정규식 이론은 50 년대로 거슬러 올라가며 어휘 분석기 (및 확장 프로그램)를 작성하는 데 중요한 역할을했습니다. 그들은 가능한 가장 적은 수의 상태를 사용하는 매우 효율적인 상태 머신을 만듭니다. 결과 상태 머신은 복잡한 패턴을 직접 작성하는 것보다 훨씬 빠르게 일치시킬 수 있습니다. 그들은 빠르기 때문에 빨리 보입니다.
riwalk

내 요점을 약간 놓쳤을 수도 있습니다. 그것들은 "빠른"것일 수도 있지만 모든 상대적인 것입니다. 아직도해야 할 일이 많이 있습니다. 다른 답변 중 일부는 읽기도 가능합니다.
빨리 _ 지금

이 답변이 질문과 관련이 있습니까? 그리고 어떻게 13 upvotes?
사다 난드

7

왜 문서를 검색하는 것보다 빠르다고 생각합니까?

예를 들어 몇 가지 트릭이 있습니다. A로 시작하고 B로 끝나는 10 글자 단어를 검색하는 경우 A를 찾은 다음 문자 9 위치가 B가 아닌 경우 일부를 건너 뛸 수 있습니다. 참조 크 누스 - 모리스 - 프랫 알고리즘을


5

정규 표현식이 빠른 이유는 무엇입니까?

실제로는 그렇지 않습니다. 그렇게 많지 않습니다. 그것은 우리 대부분이 알아 차릴만큼 느리지 않다는 것입니다. 예전의 느린 시절로 돌아 가면 훨씬 더 눈에 띄었습니다.

또한 모든 작업에 적합한 도구 인 망치아닙니다 .


+1 그 특별한 예술 작품을 상기시켜 주셔서 감사합니다 ...
yannis

5

대부분의 라이브러리는 많은 개발자들이 수년 동안 노력한 결과로 가능한 한 마지막 성능을 최대한 발휘하기 때문에 RegEx의 코드 작성 속도훨씬 빠릅니다 . 한 개인이 자신의 검색 코드로 복제하기가 어렵습니다.


4
s / squeak / squeeze /?
Péter Török

4

기본 전제는 잘못되었습니다.

정규식이 단순한 검색보다 항상 빠른 것은 아닙니다. 그것은 모두 상황에 달려 있습니다. 표현의 복잡성, 검색되는 문서의 길이 및 전체 요인에 따라 다릅니다.

정규식은 간단한 파서 (시간이 걸리는)로 컴파일됩니다. 따라서 문서가 작 으면이 추가 시간이 유리합니다. 또한 표현식이 단순하면 정규 표현식으로 인해 이점이 없습니다.

표현이 복잡하고 문서가 충분히 크면 몇 가지 이점을 얻을 수 있습니다. 이것이 정규 표현식을 더 빨리 고려할만큼 충분한 지 여부는 검색에 얼마나 많은 노력을 기울이고 있는지에 따라 크게 달라집니다 (정규 표현식에는 라이브러리가 사용자가 생각하지 않았을 수있는 최적화가있을 수 있음).

내가 말하려는 것은 일반화 된 담요 답변이 없다는 것입니다. 특정 표현식 (및 알려진 문서 크기)이있는 경우 간단한 검색보다 표현식이 빠른지 여부와 그 이유에 대한 예 / 아니오 답변을 도출 할 수 있습니다.

정규 표현식의 실제 장점은 일단 작성하는 방법을 이해하면 복잡한 검색을 간결하게 표현할 수 있다는 것입니다. 일반화 된 양식이므로 일반적인 경우에 유용한 방식으로 검색 할 수있는 도구를 작성할 수 있습니다. 일반적으로 최소한 간단한 검색만큼 빠릅니다 (최소 크기의 문서에서; 이보다 작은 문서에서는 속도가 느리더라도 여전히 빠르기 때문에 중요하지 않습니다).


1

일부 고급 언어 (아마도 자바 스크립트)에서는 저급 언어 (아마도 C)로 구현 된 정규식 라이브러리를 사용하는 것이 고급 언어로 파서 논리를 작성하는 것보다 빠를 것입니다.

그럴듯한-이것이 실제로 사실인지 전혀 모른다.


좋은 것! 그것은 나도 고려한 것입니다. 그러나 오늘날의 프로세서가 이전 프로세서보다 훨씬 빠르므로 코드를 효율적으로 작성하면 차이점을 거의 말할 수 없습니다. 나는 실제로 전체 정규 표현식 빠른 가설에 대해 실제로는 아닙니다! ;-)
user3833732
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.