正規表現はプログラミング言語ですか?


27

学術的な意味では、正規表現はプログラミング言語として認められますか?

私の好奇心のための動機は、SOの質問尋ね、私はただ見「Xを行うとregexができますか?」そして、それらを使用する可能性のある解決策について一般的な意味で何が言えるのだろうかと思いました。

私は基本的に「正規表現チューリングは完了していますか?」


9
それで基本的に、「正規表現はチューリング完全ですか?」
FrustratedWithFormsDesigner

誰かがさらに詳しく説明してもいいと思いますが、はい
アーロンアノディード

4
「完全な正規表現である」には、言語の種類とチョムスキー階層を

5
(編集より1分後)そして質問と説明の道をたどりたい場合は、cs理論交換をご覧ください。ポンプの補題は、最も単純な反証である「正規言語が一致することができます^ ^ NB N」(チューリングマシンによって整合可能です)。

1
彼は「プログラミング言語」セクションの履歴書にそれを載せることができるかどうかを尋ねていると思います。その場合の答えはノーです。これは「技術」セクションの下にあります。
ニール

回答:


46

正規表現は、形式言語理論で「正規言語」として知られる文字列およびその他のテキスト情報を解析するために使用される特定の形式の文法です。これらはプログラミング言語ではありません。これらは、コーディングの省略形であり、実装するのが非常に面倒であり、時々不可解な見た目の正規表現よりもさらに複雑です。

プログラミング言語は通常、チューリング完全な言語として定義されます。そのような言語は、計算可能な機能を処理できなければなりません。正規表現はこのカテゴリに該当しません。

正規表現のような言語が必要な場合は、Jを試してください。


1
+1、私は見たが、正規表現のチューリング完全性の良い議論/反証を見つけることができなかった。
FrustratedWithFormsDesigner

1
@ davidk01-セルオートマトンは完全にチューリングできます(優れたコンパイラーを見つけるのは難しいですが)が、正規表現はそうではありません。自明ではない計算を行うことはできますが、そうすることはできません。チューリング完全セルラーオートマトンは、プログラミング言語と見なすことができます。これは、原則として、他の言語で作成できるプログラムを作成できるからです。
psr

1
また、素数性テストを実行する正規表現(montreal.pm.org/tech/neil_kandalgaonkar.shtml#primality_regex)は、学術的な意味で「正規表現」よりも強力なperl正規表現の機能を使用していることに注意することも重要です。 。通常の言語は、任意のメモリを必要としません。
エリックW.

5
@WorldEngineer:チューリング完全ではない、興味深く有用なプログラミング言語があります。データログ、SQL、およびACL2が思い浮かぶいくつかの例であり、型理論ベースの定理証明器のようなもので使用される任意の数の強く正規化されたラムダ計算です。
ライアンカルペッパー

1
すべてのプログラミング言語が完成しているわけではありません。たとえば、インタプリタとペアになっていないと完全にチューリングされないXMLのような純粋にコンテキストフリーの宣言型言語は、プログラミング言語と見なすことができます。それはすべて、「プログラミング言語」の定義に依存します。「通常の」言語を「コンテキストのない」言語に変換するために必要なのは、プッシュダウンスタックだけです。それから、それはずっと亀です。
エヴァンプライス

14

討論の参加者がXYの異なる定義を使用する場合、「is X a Y」タイプの質問に答えることは困難です。一部の定義では、答えは「はい」であり、一部の定義では、答えは「いいえ」である可能性があります。特に、答えが異なる定義が異なる技術的な詳細に依存する場合。また、このディスカッションにはいくつかの誤った情報が含まれているため、より長い回答をお待ちください。

プログラミング言語」とはどういう意味ですか?

簡単な答えは、「プログラムの作成に使用される言語」です。もちろんですが、どのようなプログラムですか?何作成するために使用することができ、言語に関するいくつかのプログラムの種類を、しかし、プログラムのではない他の種類?極端な場合を説明する2つの具体例を次に示します。

1)Mと呼ばれる架空の言語は次のように機能します。プログラムに1つの文字「m」が含まれている場合、マインスイーパのゲームが作成されます。それ以外はすべて構文エラーです。

直感的には、これは「プログラミング言語」と言うことではありません。しかし、Mのマーケティング部門は、プログラムの作成に使用できるため、技術的に定義を満たしていると主張できます。確かに、コンパイラはいくつかの重要な部分をあなたのために行いますが、それはコンパイラがすることですよね?C言語のコンパイラは、いくつかの単純な単語を多数のプロセッサ命令に変換します。Mコンパイラーはさらに先へ進み、作業をさらに簡単にします。

2)有名なTurbo Pascalのオリジナルバージョンをインストールすると、多くの種類のプログラムを作成できます。ただし、必要なAPIが存在しないため、Webブラウザーで実行するゲームを作成することはできません。

それでは、Turbo Pascalをプログラミング言語にしているのに、Mにはないものは何ですか?簡単に言えば、MよりもPascalの方が多くのことができます。しかし、Webブラウザーで実行される掃海艇ゲームを作成するM.NETがあるとします。これで、PascalでできることとM.NETでできないことができましたが、M.NETでできることとPascalでできないこともあります。Pascalの利点を重要視し、M.NETの利点を無関係と考える必要があるのはなぜですか?

答えは、Pascalですべての種類のアルゴリズムを書くことができるが、MまたはM.NETでアルゴリズムを書くことはできないということです。確かに、Mはコマンド「m」をコンパイルし、Cはコマンド「strcmp」をコンパイルします。しかし、「strcmp」をより大きなコンテキストに置くことができます。たとえば、2つのファイルを行ごとに比較したり、1000個の文字列を読んでアルファベット順に並べ替えたり、... そして、プログラミング言語の本質をなすのは、アルゴリズムで特定のコマンドを使用するまさにその能力です。

アルゴリズムとは正確には何ですか、さらに重要なことは、「任意のアルゴリズム」とは何ですか コンピューターサイエンスでは、チューリング完全という言葉を使用します。アイデアは、それぞれがすべてをシミュレートできるコンピューター言語のセットがあるということです。これらの言語の1つがチューリングマシンです。Pascalがあり、Cがあり、Javaがあり、Pythonがあり、Lispがあり、Smalltalkがあり、XSLTさえあります。架空のMとM.NETはありません。これについては、適切なコンピューターサイエンスコースを提供しているどの大学でも詳しく学ぶことができますが、アイデアはチューリング完全言語で何でもできるということです。必要最小限のAPIを提供すれば、別のチューリング完全言語でできること。(PascalにWebブラウザーAPIを提供すると、Webブラウザーであらゆる種類のゲームを作成できます。MにWebブラウザーAPIを提供しても、Minesweeperを作成できるのはまだです。)プログラミング言語からすべてのAPIを削除すると、重要なものが残ります。

正規表現」とはどういう意味ですか?

異なるプログラミング言語は、それらをわずかに異なる方法で実装します。しかし、元のアイデアは、正規表現がいわゆる正規言語を表現するというものでした。ここではプログラミング言語について話すのではなく、(疑似)人間の言語について話すことに注意してください。「ba」、「baba」、「bababa」などの単語だけで構成される言語を話すエキゾチックな部族を見つけたとします。この言語は、「1回以上繰り返される音節「ba」」として、または「(ba)+」として正規表現を使用して、口頭で説明できます。

正規表現は、「nothing」、「this letter」、「this、続いてthat」、「this or that」、「this、繰り返された1回以上」、「not this」を表現することになっています。-それが数学的な定義です。それ以外は、以前のコンポーネントから作成された便利なショートカットです。たとえば、「this、two or three times」は「this、then this、after(this or nothing)」と翻訳できますが、「baba」よりも「ba {2,3}」と書く方が便利です(ba)?」

実際には、「正規表現」の典型的な実装はこれ以上のものを実装しています。例えば、数学的定義、「ABA」、「aabaa」、「aaabaaa」の言語などに用い-続く「」Sの任意の数、「B」に続く、同じ A」の数を「s」は通常の言語ではありません。ただし、今日使用されている多くの「正規表現」は、「(a +)b \ 1」と書かれた「以前と同じもの」という追加の概念を使用して検出できます。この追加の概念を使用すると、素数の文字で構成される単語を検出するなど、いくつかのクールなことができます。それでも、アルゴリズムを実行することはできません...理由の説明のために、

それで、元のトピックに戻ります:正規表現(Chomsky階層の正規言語を記述する表現、または前者に加えて\ 1操作として定義される)はプログラミング言語(チューリング完全として定義される)ですか?答えはノーです。いいえ、あなたが実装することはできません任意のアルゴリズムを正規表現を使用して、および実装する能力任意のアルゴリズムは、コンピュータサイエンスを勉強し、人々は通常、プログラミング言語の本質として理解するものです。

もちろん、誰でも異なる定義を主張することで答えを変えることができます。最初に書いたように、ここでは技術的な詳細が重要です。あなたがそれらを間違えた場合、あなたは間違った答えを得る。

また、技術的な詳細に興味がない場合は、答えは次のようになります。プログラムを作成するために正規表現を使用できますか?いいえ。なぜプログラミング言語と呼ぶのですか?(ただし、このような回答がダウンロードされ、ここで削除されたため、この長いバージョンを作成しました。)

編集:また、誰でも「正規表現」の新しいバリアントを実装するライブラリを作成でき、いくつかの新しい機能が追加されています。ある時点で、システム全体がチューリング完全になるには、新しい機能で十分かもしれません。些細な例は、新しい構文を使用してチューリング完全言語を埋め込むことです。しかし、それはあまり明白ではありません。たぶんそれはすでに起こった。


0

.Netでは、Regexは、代替とルックアラウンドのさまざまな組み合わせを使用して、複数の形式の条件を処理できるだけでなく、独自のスタックを操作することもできます。

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

これは、たとえば、HTMLテーブルを取得するために作成した小さなスニペットです。他の正規表現エンジンとは異なり、これはキャプチャコレクションのスタック(プッシュ、ピーク、ポップ)を制御し、ネストされたオブジェクトを処理できます。私はもっ​​と複雑なものを持っていますが、それはかなり独自のものです。

この例では、プログラミング言語の基本的な要件をすべて満たしていると見なすことができます。変数、インラインメモリ、条件、入力および出力があり、複数の正規表現コンパイルエンジン(この場合は.Net)の1つを使用してコンパイルします。

(NEVER)への過剰使用squawkingへの対応パース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プログラムで実際に使用する必要があります。
スアメア

3
ああ、これはhtmlを解析するために正規表現を使用してはならない理由の基本的な証拠です。今まで。
タクロイ

@Tacroy Niceが、正規表現を使用したHTMLの解析に関するオウムのアドバイスに誰かが賛成してくれたのを見てくれました。気弱な人向けではありませんが、上記のような正規表現とスタックを組み合わせることは、コンテキストのないパーサーを構築するための基本的な(そして効率的な)レシピです。
エヴァンプライス

1
オウムの鳴き声に応えて。:私は、この作成したHTML解析
Suamere

コンテキスト依存言語を受け入れる場合、正規表現ではありません。Regexのスーパーセットである他のDSLです。ベンダー名は変わりません
-Caleth

0

以前の回答で説明したように、正規表現の検索/置換はチューリング完全なプログラミング言語ではありませんが、正規表現で置換する繰り返しアクションを使用できる場合、はい、正規表現を使用してチューリングマシンをエンコードできます:

正規表現による検索/置換の繰り返しは、チューリング完全プログラミング言語です

その結果、同じ検索を使用して計算可能な関数を計算し、javascriptの正規表現を何度も置き換えることができます。

チューリング完全性を証明するには、正規表現の検索/置換でチューリングマシンをエンコードするだけで十分です。エディターの状態は次のとおりであると仮定します。

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#

およびその置換式(javascriptのような)

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

さて、今では多くのルールをエンコードする方法は?正規表現の検索にはor演算子との連結を使用し|、結果を置換で組み合わせ、グループ番号をオフセットで数値化します。たとえば、4つのルールのセットを考えてみましょう。

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

お気に入りのJavaScriptエンジンで試してみてください。

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.