정규식은 프로그래밍 언어입니까?


27

학문적 의미에서 정규 표현은 프로그래밍 언어로 인정됩니까?

호기심에 대한 동기 부여는이다 SO 질문 질문에 난 그냥 보았다 "X를 할 정규식 수 있습니까?" 그리고 그것을 사용하여 가능한 솔루션에 대해 일반적인 의미로 말할 수있는 것이 궁금합니다.

기본적으로 "정규 표현식 튜링이 완료 되었습니까?"


9
기본적으로 "정규 표현식 튜링이 완료 되었습니까?"
FrustratedWithFormsDesigner

누군가가 더 자세히 설명하면 멋지지만, 그렇습니다
Aaron Anodide

4
언어 유형의 이해와 필요 "완전한 튜링 정규 표현식은" 촘스키 hierchary

5
(편집 1 분 후) 질문과 설명의 경로를 따라 가려면 cs 이론 교환 을 살펴보십시오 . 펌핑 보조 정리는 가장 간단한 반증이다 "정규 언어가 일치 할 수있는 ^ NB ^ N"(튜링 기계에 의해 정합 가능한이다).

1
"프로그래밍 언어"섹션에서 이력서를 제출할 수 있는지 묻고있는 것 같습니다. 이 경우의 대답은 '아니오'입니다. "기술"섹션에 있습니다.
Neil

답변:


46

정규 표현식은 공식 언어 이론에서 "일반 언어"로 알려진 문자열 및 기타 텍스트 정보를 구문 분석하는 데 사용되는 특정 유형의 공식 문법 입니다. 그것들은 프로그래밍 언어가 아닙니다. 그들은 때로는 간헐적으로 보이는 Regex보다 구현하기가 매우 지루하고 혼란 스러울 수있는 코딩의 속기입니다.

프로그래밍 언어는 일반적으로 튜링 완료 언어로 정의됩니다 . 이러한 언어는 계산 가능한 기능 을 처리 할 수 ​​있어야 합니다 . 정규식은이 범주에 맞지 않습니다.

정규식처럼 보이는 언어를 원한다면 J를 사용해보십시오.


1
+1, 나는 보았지만 정규 표현식의 튜링 완성도에 대한 좋은 토론 / 증거를 찾을 수 없었습니다.
FrustratedWithFormsDesigner

1
@ davidk01-셀룰러 오토마타는 튜링 완료 될 수 있지만 (좋은 컴파일러는 찾기 어렵지만) 정규 표현식은 아닙니다. 사소한 계산을 할 수는 있지만, 할 수없는 사소한 일이 있습니다. Turing Complete Cellular Automata는 프로그래밍 언어로 간주 될 수 있습니다. 원칙적으로 다른 언어로 수행 할 수있는 프로그램을 작성할 수 있기 때문입니다.
psr

1
또한 우선 순위 테스트를 수행하는 정규식 ( montreal.pm.org/tech/neil_kandalgaonkar.shtml#primality_regex )은 학술적 의미, 즉 저장된 그룹에 비해 "정규 표현식"보다 강력한 펄 정규 표현식의 기능을 사용 한다는 점에 유의해야합니다. . 일반 언어에는 임의의 메모리가 필요하지 않습니다.
Eric W.

5
@WorldEngineer : Turing이 완성되지 않은 흥미롭고 유용한 프로그래밍 언어가 있습니다. 데이터 로그, SQL 및 ACL2는 몇 가지 예이며, 유형 이론 기반 정리 프로 버와 같은 것에 사용되는 강력하게 정규화되는 람다 계산법의 수입니다.
Ryan Culpepper

1
모든 프로그래밍 언어가 완전하지는 않습니다. 예를 들어, 인터프리터와 쌍을 이루지 않고 완전하지 않은 XML과 같은 컨텍스트가없는 선언적 언어는 프로그래밍 언어로 간주 될 수 있습니다. 그것은 모두 '프로그래밍 언어'의 정의에 달려 있습니다. '일반적인'언어를 '문맥없는'언어로 변환하기 위해 필요한 것은 푸시 다운 스택입니다. 그런 다음 거북이가 끝까지 내려옵니다.
Evan Plaice

14

토론 참가자가 XY 의 다른 정의를 사용하는 경우 "is X a Y " 유형의 질문에 대답하기가 어렵습니다 . 일부 정의의 경우 대답은 "예"이고 일부 정의의 경우 대답은 "아니오"일 수 있습니다. 특히 답변 이 다른 정의가 다른 기술적 세부 사항에 의존하는 경우. 또한이 토론에는 잘못된 정보가 포함되어 있으므로 더 긴 답변으로 인내심을 가지십시오.

" 프로그래밍 언어 " 란 무엇을 의미 합니까?

간단한 대답은 "프로그램 작성에 사용되는 언어"일 수 있습니다. 그러나 어떤 종류의 프로그램입니까? 만드는 데 사용할 수있는 언어에 대한 어떤 일부 프로그램의 종류,하지만 프로그램이 아닌 다른 종류의? 다음은 극단적 인 경우를 설명하기위한 두 가지 구체적인 예입니다.

1) M이라는 가상의 언어는 다음과 같이 작동합니다. 프로그램에 단일 문자 "m"이 포함되어 있으면 지뢰 찾기 게임을 만듭니다. 다른 모든 것은 구문 오류입니다.

직관적으로 이것은 "프로그래밍 언어"라고 말하는 것이 아닙니다 . 그러나 M의 마케팅 부서 는 프로그램을 만드는 데 사용될 있기 때문에 기술적 으로 정의를 충족 한다고 주장 할 있습니다. 물론, 컴파일러는 당신을 위해 중요한 부분을 수행하지만 이것이 컴파일러가하는 일입니까? C 언어의 컴파일러는 간단한 단어를 수십 개의 프로세서 명령어로 변환합니다. M 컴파일러는 더 나아가 작업을 더욱 단순하게 만듭니다.

2) 유명한 Turbo Pascal의 원래 버전을 설치하면 많은 종류의 프로그램을 작성할 수 있습니다. 그러나 필요한 API가 없기 때문에 웹 브라우저에서 실행되는 게임을 작성할 수 없습니다.

그렇다면 터보 파스칼을 프로그래밍 언어로 만드는 것은 무엇입니까?하지만 M에는 없습니다. 간단히 말해서 M보다 Pascal에서 더 많은 것을 할 수 있지만 웹 브라우저에서 Minesweeper 게임을 실행하는 M.NET이 있다고 상상해보십시오. 이제 파스칼이 할 수 있고 M.NET이 할 수없는 것이 있지만, M.NET이 할 수 있고 파스칼이 할 수없는 것도 있습니다. 파스칼의 장점과 M.NET의 장점이 중요하지 않은 이유는 무엇입니까?

정답은 Pascal에서 모든 종류의 알고리즘 을 작성할 수 있지만 M 또는 M.NET에서는 알고리즘 을 작성할 수 없다는 것 입니다. 물론, M은 명령 "m"을 컴파일하고 C는 명령 "strcmp"를 컴파일합니다. 그러나 더 큰 맥락에서 "strcmp"를 넣을 수 있습니다. 예를 들어 두 파일을 한 줄씩 비교하거나 수천 개의 문자열을 읽고 알파벳순으로 정렬하거나 수백만 가지를 정렬 할 수 있습니다. 그리고 프로그래밍 언어의 본질을 만드는 모든 알고리즘 에서 주어진 명령을 사용하는 것이 바로이 기능 입니다.

알고리즘은 정확히 무엇이며, 더 중요한 것은 "모든 알고리즘"이란 무엇입니까? 컴퓨터 과학에서는 Turing-complete 라는 단어를 사용합니다 . 아이디어는 각 언어가 모든 언어를 시뮬레이션 할 수있는 컴퓨터 언어 세트가 있다는 것입니다. 이러한 언어 중 하나는 튜링 기계입니다. 이것이 바로 이런 방식입니다. 파스칼, C, 자바, 파이썬, 리스프, 스몰 토크, XSLT도 있습니다. 우리의 가상 M과 M.NET은 없습니다 . 양질의 컴퓨터 과학 코스를 제공하는 모든 대학에서 더 많은 것을 배울 수 있지만 아이디어는 Turing-complete language가 무엇이든 할 수 있다는 것입니다필요한 최소한의 API를 제공하면 다른 Turing-complete 언어로 할 수 있습니다. (파스칼에 웹 브라우저 API를 제공하면 웹 브라우저에서 모든 종류의 게임을 만들 수 있습니다. 웹 브라우저 API를 M에 제공하면 여전히 지뢰 찾기 만 만들 수 있습니다.) 우리는 은유 적으로 말할 수 있습니다. 프로그래밍 언어에서 모든 API를 제거하면 중요한 것은 남아있는 것입니다.

" 정규 표현식 " 은 무엇을 의미 합니까?

다른 프로그래밍 언어는 약간 다르게 구현합니다. 그러나 원래의 개념은 정규 표현식이 소위 정규 언어를 표현한다는 것이 었습니다 . 여기서는 프로그래밍 언어가 아니라 (의사) 인간 언어에 대해 이야기합니다. "ba", "baba", "bababa"등의 단어로만 구성된 언어를 말하는 이국적인 부족이 있다고 가정 해보십시오. 이 언어를 구두로 "한 번 이상 반복 된 음절 'ba'"또는 정규식을 "(ba) +"로 사용하여 설명 할 수 있습니다.

정규식은 "아무것도", "이 글자", "이것, 그 다음에", "이것 또는 저것", "이것, 한 번 이상 반복됨", "이것이 아님"으로 표현됩니다. 그것은 수학적 정의입니다. 다른 것은 이전 구성 요소에서 만든 편리한 바로 가기입니다. 예를 들어, "이, 두세 번 반복"은 "이 다음에이 다음에 (이것 또는 아무것도 없음)"으로 번역 될 수 있지만 "baba"보다 "ba {2,3}"을 작성하는 것이 더 편리 할 수 ​​있습니다. (ba)? "

실제로 "일반 표현식"의 일반적인 구현은 이보다 더 많은 것을 구현 합니다. 예를 들어, 수학적 정의를 사용하여 "aba", "aabaa", "aaabaaa"등의 언어- "a"와 "b", 같은 수의 "a" "s- 는 일반 언어 가 아닙니다 . 그러나 오늘날 사용되는 많은 "정규 표현식"은 "(a +) b \ 1"로 작성된 "이전에 찾은 것과 같은"추가 개념을 사용하여이를 감지 할 수 있습니다. 이 추가 개념을 사용하여 몇 가지 멋진 작업을 수행 할 수 있습니다 (예 : 소수 의 문자 로 구성된 단어 감지) 아직도, 우리는 어떤 알고리즘도 할 수 없습니다 ... 왜냐하면

원래 주제로 돌아가서 : 정규 표현식 (Chomsky 계층 구조에서 정규 언어를 설명하는 표현식으로 정의되거나 전자와 \ 1 연산으로 정의)이 프로그래밍 언어 (Turing-complete로 정의 됨)입니까? 대답은 ' 아니요' 입니다. 아니, 당신이 구현할 수 있는 알고리즘 정규 표현식을 사용하고 구현할 수 있는 알고리즘은 컴퓨터 과학을 공부하는 사람들은 일반적으로 언어 프로그래밍의 본질로 이해하는 것입니다.

물론 누구나 다른 정의를 주장함으로써 답을 바꿀 수 있습니다 . 처음에 썼 듯이 여기에서 기술적 세부 사항이 중요합니다. 당신이 틀리면 틀린 답을 얻습니다.

당신이하는 경우와 하지 기술적 인 세부 사항에 관심이 대답은 할 수있다 : 당신은 정규 표현식 (그리고 아무것도) 프로그램을 만들 수를 사용할 수 있습니까? 아니요. 왜 프로그래밍 언어라고합니까? (그러나 이와 같은 답변이 여기에서 다운로드되어 삭제 되었으므로이 더 긴 버전을 작성했습니다.)

편집 : 또한 누구나 새로운 기능이 추가 된 "정규 표현식"의 새로운 변형을 구현하는 라이브러리를 만들 수 있습니다. 새로운 기능 으로 인해 전체 시스템이 Turing-complete가되기에 충분할 있습니다. 간단한 예는 새로운 구문을 사용하여 Turing-complete 언어를 포함하는 것입니다. 그러나 덜 분명하게 일어날 수도 있습니다. 아마 이미 일어 났을 수도 있습니다.


0

.Net에서 Regex는 서로 다른 교대 및 둘러보기 조합을 사용하여 여러 형태의 조건을 처리 할 수있을뿐만 아니라 자체 스택을 조작 할 수도 있습니다.

(?xm)
    (?>
        <(?<Tagname>table)[^>]*>
    )
(?(Tagname)
    (
        </(?(?!\k'Tagname')(?<-Tagname>))*\k'Tagname'>(?<-Tagname>)
    |
        (?>
            <(?<Tagname>[a-z][^\s>]*)[^>]*>
        )
    |
        [^<]+
    )+?
    (?(Tagname)(?!))
)

예를 들어, 이것은 HTML 테이블을 검색하기 위해 작성한 작은 스 니펫입니다. 다른 정규식 엔진과 달리 캡처 모음 (푸시, 엿보기 및 팝)의 스택을 제어하고 중첩 된 객체를 처리 할 수 ​​있습니다. 더 복잡한 것이 있지만 독점적입니다.

이 예제에서 Regex는 프로그래밍 언어의 모든 기본 요구 사항을 갖는 것으로 볼 수 있다고 생각합니다. 변수, 인라인 메모리, 조건부, 입력 및 출력이 있으며 여러 정규식 컴파일 엔진 중 하나를 사용하여 컴파일합니다 (이 경우 .Net).

정규식으로 HTML을 구문 분석하지 않기 위해 과도하게 사용 된 스 쿼킹에 대한 응답으로 미리 게시 할 수있는 미리 입력 된 응답을 게시했습니다 .HTML 구문 분석

주석 예제 (단지 데모)는 다음과 같습니다.

Function Regex("<(td>)((?:[^<]*(?(?!</\1)<))*)</\1")
    Group(0) = "<"
    Group(1) = "td>"
    Group(0) += Group(1)
    Group(2) = LoopMethod()
    Group(0) += Group(2)
    Group(0) += "</" & Group(1)
    Return Group()
End Function

Function LoopMethod()
    retGroup = ""
    Do
        tmpGroup = Everything that is NOT an Opening HTML Delimeter
        If the Text following tmpGroup Does NOT Equal "</" & Group(1) Then
            tmpGroup += "<"
            retGroup += tmpGroup
        Else
            Exit Do
        End If
    Loop
    Return retGroup
End Function

다시 한 번 HTML 앵무새의 경우 : HTML 구문 분석

이것은 루프와 조건부 (알고리즘?)를 수행하는 간단한 정규식을 보여줍니다. 유일하게 누락 된 것은 실제 수학 계산입니다. 이것은 일반적인 "(. *?)"방법보다 TD 셀을 더 효율적으로 끌어 오는보다 자세한 정규식입니다.

그러나 Regex 애호가이자 스스로를 선포하는 마스터라고해도 Regex가 프로그래밍 언어라고 말하는 사람은 없습니다. 나 자신에 대한 나의 주장은 그것이 혼자서 할 수 없으며 다른 프로그래밍 언어 엔진에 의해 지원되는 동안 자체 엔진을 통해 실행되어야한다는 것입니다.


이 "테스트"및 작동하지 않는 경우 대부분의 정규식 엔진 "테스터"가 .Net 정규식 (밸런싱 그룹)을 처리하지 않는다는 것을 알아야합니다. 실제로 이것을 .Net 프로그램에서 사용해야합니다.
Suamere

3
어이, 이것은 왜 정규 표현식을 사용하여 html을 구문 분석하지 않아야 하는지에 대한 주요 증거입니다 . 이제까지.
Tacroy

@Tacroy 누군가 정규식으로 HTML을 구문 분석하는 것에 대한 앵무새 조언을 들었습니다. 희미한 마음은 아니지만 위와 같은 정규 표현식을 스택과 결합하는 것은 컨텍스트가없는 파서를 작성하는 기본적이고 효율적인 방법입니다.
Evan Plaice

1
앵무새 스 쿼킹에 대한 답변. 나는 이것을 만들었다 : HTML 구문 분석
Suamere

상황에 맞는 언어를 허용하는 경우 정규식이 아닙니다. Regex의 상위 집합 인 다른 DSL입니다. 공급 업체 이름은 변경되지 않습니다
Caleth

0

정규식에서 하나의 찾기 / 바꾸기가 이전 답변에서 설명한 것처럼 Turing-complete 프로그래밍 언어가 아니지만 정규식으로 대체하는 반복 된 조치를 사용할 수 있으면 정규식을 사용하여 모든 Turing 기계를 인코딩 할 수 있습니다.

정규 표현식으로 반복 찾기 / 바꾸기는 Turing-complete Programming Language

결과적으로 동일한 검색을 사용하여 계산 가능한 함수를 계산하고 자바 스크립트 정규식을 반복해서 대체 할 수 있습니다.

튜링 완전성을 증명하려면 정규식 검색 / 대체로 튜링 기계를 인코딩하면 충분합니다. 편집기의 상태가 다음과 같다고 가정하십시오.

0000#12345:01-5:0#0000000

리더가있는 기호 테이프로 읽을 수 있습니다.

[left symbols]#[set of states]:[set of symbols]-[current state]:[current symbol]#[right symbols]

상태 5에서 0을 읽고 1을 쓰고 상태를 3으로 변경하고 왼쪽으로 이동하는 규칙의 경우 다음 표기법을 사용하여 추상화합니다.

5:0 => 1, 3:[left]

이전 표기법을 검색 정규식으로 인코딩합니다.

(\d)#(1)(2)(3)(4)(5):(0)(1)-5:0#

그리고 그 대체 표현 (자바 스크립트와 같은)

#12345:01-$4:$1#$8

이제 많은 규칙을 인코딩하는 방법은 무엇입니까? 정규 표현식 검색을 위해 or연산자 와 연결을 사용 |하고 그룹 번호를 오프셋과 함께 숫자를 바꿔서 결과를 대체합니다. 예를 들어, 네 가지 규칙 집합을 고려해 봅시다.

5:0 => 1, 3:left
3:0 => 1, 5:right
5:1 => 1, 5:right
3:1 => 1: 3:stop

우리는 그것들을 검색으로 인코딩하고 식을 바꿉니다.

Search:
(\d)#(1)(2)(3)(4)(5):(0)(1)-5:0#|#(1)(2)(3)(4)(5):(0)(1)-3:0#(\d)|#(1)(2)(3)(4)(5):(0)(1)-5:1#(\d)|#(1)(2)(3)(4)(5):(0)(1)-3:1#

Replace by:
$15$23#12345:01-$4$13$21$27:$1$16$24$31#$8

자주 사용하는 자바 스크립트 엔진에서 사용해보십시오.

function turingstep(s) {
  return s.replace(/(\d)#(1)(2)(3)(4)(5):(0)(1)-5:0#|#(1)(2)(3)(4)(5):(0)(1)-3:0#(\d)|#(1)(2)(3)(4)(5):(0)(1)-5:1#(\d)|#(1)(2)(3)(4)(5):(0)(1)-3:1#/g,"$15$23#12345:01-$4$13$21$27:$1$16$24$31#$8");
}

var tape = "0000#12345:01-5:0#0000000"
for(var i = 0; i < 6; i++) {
  console.log(tape)
  tape = turingstep(tape)
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.