10

同様の質問がありますが、正規表現の構文について人々がいつも与えるのと同じ古い回答が得られましたが、それはここでのポイントではないため、正規表現の構文について同じ古い回答をひざまずかないようにしてください。今回は、もう少し独創的で個人的なものにしてください。

正規表現の構文は非常にコンパクトで、コンパクトすぎて適切ではありません。これはコード ゴルフのようなものであり、誰もがコード ゴルフが製品コードでは良いことではないことに同意します。ただし、ほとんどの人は正規表現構文を受け入れますが、これは控えめに言っても矛盾しているようです。

したがって、次のようなよく耳にする防御策があります。

  • 答え: コンパクトです

  • Counter : この時代、コードは読み書きができるべきであり、"client" のような変数は "c" よりも優れているということに、私たちは皆同意していませんか?

  • 回答: 「ドメイン固有言語」です。

  • Counter : SQL や LINQ のような非常に理解しやすく、コンパクトでなく、暗号化されておらず、あえて言うならきれいなドメイン言語についてはどうですか?

  • 回答: 一度知ってしまえば簡単に理解できます。

  • カウンター: ほとんどの優れた言語は、使用したことがなくても簡単に理解できます。たとえば、Python を見たことがなくても、誰でも簡単に Python に飛び込むことができます。また、Regex を見るのが非常に難しい言語であるのに、なぜ人々は Regex を擁護し、さらに Lisp の括弧について文句を言うのでしょうか?

さて、ここでは誰もが独創的で正直であるように努めます。正規表現を設計するために 20 年前にプログラマーが使用したのと同じ古い暗記回答を引き出すだけではありません。それらがこの時代に有効な命題であると本当に信じている場合を除きます。


編集:記録のために、私は何年も前から正規表現を知っており、今日でも頻繁に使用しており、それらを理解することさえあります。しかし、正規表現について「真実」として捉えてきたものを再考し、現代的な観点からそれらを見る時が来たのではないかと突然感じました。主な理由は、さらなる発展のために原則に疑問を抱くことが必要であり、非常に多くの新参者がそれらについて激しく不満を漏らしているため、彼らはただ完全に平気でいることができないため、私は新参者の靴に足を踏み入れて、いくつかの良い点を考えてみることにしました.正規表現に対して。

主観的であることに関しては、これが当時のプログラマーのジョークほど主観的ではないか、プログラマーとの関連性が低いとは思いません。それどころか、それは非常にプログラマーに関連しています。

議論に関しては、それが質問のポイントです。正規表現の時代遅れの構文に賛同する良い議論を得るために、それは新参者がなぜ正規表現が何であるかを実際に理解するのに役立ちます。正規表現の「クールさ」に目がくらんでいます。


見積もり:

Perl 5.10 の正規表現に関するドキュメントは、非常に多くのこっけいな機能が構文に忍び込み、誰も適切なドキュメントを書くことができなくなったため、読めない戯言の山に溶けてしまいました。

正規表現が維持できなくなったと言いたいのですか?それでは、優れたプログラマーとして、それらをリファクタリングすることを検討する必要がありますか? たぶん、他の多くのテクノロジーで行ったように、クリーンアップして再試行しますか?

4

19 に答える 19

35

私が言わなければならないことのほとんどは、Adam と DGM によって対処されましたが、あなたの 2 番目のポイントを十分にカバーしているとは思いません。

「SQL や LINQ のような非常に理解しやすく、コンパクトでなく、暗号化されておらず、あえて言うならかなりのドメイン言語はどうですか?」

これに対する答えを表現する良い方法は、正規表現を説明するために英語をどのように使用しますか? と尋ねることだと思います。

<TAG\b[^>]*>(.*?)</TAG>

"<TAG" を探します '>' 以外の 0 個以上の単語境界の後に '>' が続く 0 個以上の何かを記憶し、最初の "</TAG>" で停止します

これはかなり単純な正規表現です。英語のフォームは本当に理解しやすいですか?もっとうまくできますか?

正規表現は読みにくいですが、正規表現から何を求めているかを説明するのは同じくらい難しい場合があります。

于 2008-11-05T05:04:23.213 に答える
27

質問の反対側を見てください: すべての機能、一貫性、簡潔さ、および堅牢性を正規表現として具体化しながら、よりプログラマーフレンドリーな新しい構文をどのように設計しますか?

于 2008-11-05T04:00:42.903 に答える
18

あなたの反論は怪しいです。正規表現の構文を知っていますか、それとも無知から議論していますか? 自分のバイアスを確立することが重要なポイントです。

  • コードゴルフとは全然違います。あなたとのつながりがよくわかりません。同じ引数を使用しているポインターまたは何か他のものについて不平を言ってみませんか?

  • 正規表現のコンパクトさは、貧弱な変数名とは何の関係もありません。c という名前の変数は何でもかまいません。正規表現の構文はあいまいでも曖昧でもありません。そのパターンを正確に説明しています。

  • それはDSLです。だったら?SQL で複雑なことをしようとしたことがありますか? こちらも大混乱。同じことをより多くの入力とより多くの構文を必要とするようにしても、状況は改善されません。私が教えているほとんどの人は、正規表現に問題を抱えています。構文が特殊だからではなく、パターンを考えたりデザインしたりすることに慣れていないからです。

  • 一度知ってしまえば簡単です。そうですね。電動工具は、初心者や習いたくない人向けには最適化されていません。私は Lisp の括弧について不満はありませんが、正規表現の構文は気にしません。

正規表現を使用したくない場合は、使用しないでください。文字列操作関数またはパーサーを使用します。他のツールを使用してください。あなたがそれで忙しい間、私は流れに逆らって泳いでいるわけでも、私がやり遂げられない仕事をツールのせいにしているわけでもありません。

どれだけの仕事をしたいかはあなた次第です。最速でそこにたどり着くツールを見つけて、それを学びましょう。それが嫌なら、もっといいものを発明してください。それまでは、文句を言うのをやめてください。

于 2008-11-05T04:29:32.893 に答える
17

これは実際には、米国退職プログラマー協会が、Python と Java で歯を削った今日の若いウィッパースナッパーに対して永続化した陰謀です。私たちは、3文字のニーモニックを備えた小さなコアメモリと難解な言語の課題を巧みに克服した神秘家への畏敬の念と敬意を維持する必要があります...そしてそれを気に入りました. 上り坂...両方向...雪の中。:-)

于 2008-11-05T04:28:47.153 に答える
11

アルゴリズムとマシンのコースを受講したときに学んだ表記法と (ほぼ) 一致するため、正規表現構文を擁護します。指定された通常の言語を取り込むマシンを生成する簡単な方法です。

探している動作を完全に記述するために必要なのは、正規表現構文だけであるためです。

于 2008-11-05T04:14:44.577 に答える
9

できます!!
すべての主要なプログラミング言語に拡張機能があり、十分に文書化およびテストされており、正規表現ほど圧縮されていないが、冗長すぎない(冗長=イライラする)読みやすい言語があれば、それについてもっと知りたいです

于 2008-11-05T04:14:17.713 に答える
8

正規表現の問題のいくつかは、言語そのものではなく、人々が正規表現を何に使おうとしているのかということです。本当に欲しいのがかなり単純なパーサーである場合、彼らは正規表現の行と行を書き込みます。

正規表現は、単純なものから適度に複雑な部分文字列の一致およびデータ抽出に最適です。しかし、ある時点で複雑になると、コンパイラー・コンパイラーを取り出して、実際のパーサーを作成する必要があります。多くの人は、正規表現が主に照合用であり、解析用ではないことを認識していないと思います。

于 2008-11-05T05:26:04.790 に答える
7

他の人はこれをほのめかしましたが、それは明確に述べることに耐えます:

正規言語はプログラミング言語とは異なります。それらは数学表記に近いです。

コンパクトさと奇抜さは、簡潔さや難読化を意図的に試みるよりも、ASCII文字から正確な表記を強制しようとした結果です。

于 2008-11-06T01:03:54.260 に答える
7

正規表現は、ハイエンドの電動工具 (つまり、建設業界の意味での電動工具) と見なす必要があります。

小屋用の小さな作業台を作る場合は、釘打ち機、チェーンソー、産業用ルーターを引き出す必要はありません。のこぎり、釘、ハンマーを使用します。

同様に、どこかにクレーンがなければ、30 階建ての建物を建てることはできません。

アイデアは、仕事に適したツールと自分のスキルレベルに適したツールを使用することです.

木を切り倒さなければならない場合は、チェーンソーを始動する前に、キックバックについて十分に理解しておいてください。そうでない場合は、代わりに手のこぎりを使用して、切断された手足を再び取り付けるために病院に行く必要がありません.

私はチェーンソーを使うのと同じように、正規表現を非常に慎重に使用しています。このツールが気に入らない場合は、使用しないでください。それを正しく使用する方法を学ぶと、物事をより速く成し遂げることがはるかに簡単になることがわかります.

于 2008-11-05T04:18:56.377 に答える
6

SQL に似た正規表現言語は魅力的なプロジェクトになると思います。誰かがそれを作成するのを見たいです。

書ける言語を持たない理由

LOOK FOR "<TAG"

THEN WORDBOUNDARY THEN ZERO-OR-MORE NOT('>') FOLLOWED-BY '>'

THEN ZERO-OR-MORE SOMETHING REMEMBERED

THEN NEAREST "</TAG>"

とはいえ、対象読者が誰なのかはわかりません。正規表現の学習にずっと時間を費やしてきたので、私はそれを使用するとは思いません。

確かに、「これほど複雑な式を使用する必要がある人々」のセットは、それと同じくらい複雑でより多くのものを日常的に処理しなければならないプログラマーのセットにほとんど対応していますか?

于 2008-11-05T05:43:07.613 に答える
6

Pyparsing ( http://pyparsing.wikispaces.com/Examples ) は、"Hello, World!" を解析する次の行のように、非常に読みやすい正規表現のような式を簡単に記述できるようにする Python ライブラリです。

from pyparsing import Word, alphas
greet = Word( alphas ) + "," + Word( alphas ) + "!"
greet.parseString("Hello, World!")

ライブラリは、正規表現の力に匹敵する能力に非常に近いようです (上記の例のページを参照してください)。

于 2008-11-05T16:23:13.967 に答える
6

正規表現のもう 1 つの問題は、さまざまな種類があることです。.Net 正規表現と php 正規表現とその他の正規表現はすべて似ていますが、同じ結果にはなりません (まったく結果が得られない場合もあります)。

于 2008-11-05T04:00:27.180 に答える
5

これらはBNF表記法などに似ており、多くの優れた言語仕様の基礎となっています。したがって、このような表記法は、期待される文字のクラスを示すためにレクサーで使用されることは理にかなっています。基本シンボルは実際にはそれほど不可解ではありません。

それから、UNIXが1行で何でもできるというアイデアが引き継がれたと思います。sedおよびgrepスクリプトが改善された後、正規表現は新しい力を獲得しましたが、それらの略記です。Larry Wallは、テキストを解析するための一般的なツールとしてそれらをPerlに組み込みました。私はそれがperlでまだ重要であったonelinersのためにコンパクトさを保持したと思います。そして、一般的なキャラクタークラスの省略名があり、さらに多くの力が正規表現に求められ、与えられました。もちろん、Perlはモジュールの言語でもあったため、正規表現構文もステートメントのブロックで機能し、より広く知られている構文を活用しました。

それらがJavaに組み込まれたことが、人々にそれらを見てもらいました、IMO。Javaはそれらに対応するために何もしませんでした。その結果、中程度の難易度のバックスラッシュを使用した表現は、バックスラッシュの密集したジャングルに変わりました。Javaは、正規表現に新しい市場を提供しましたが、それは最も凶悪な形式です。それらを見て、もう注意を払わなかった場合、正規表現はあるべきではないものであると思うかもしれません。

十分に明確な構文が与えられた場合、Ambroseの冗長バージョンの場合、誰かがPerlのモジュールを考え出し、冗長正規表現を取得して、Perlが理解できるコンパクトな正規表現に「コンパイル」し、より単純な正規表現overload::constantsまたは場合によってはParse::RecDescent文法を使用できるのは興味深いことです。 。

于 2008-11-05T15:49:14.597 に答える
4

正規表現は(少なくとも元々は)正規言語を記述します。正規言語は、決定性有限オートマトンによって記述および記述できるという点で、非常に優れた理論的特性を備えています。自明でない正規表現のDFAは、手作業でコーディングするのが面倒です。

さらに重要なことに、perlなどのバックエンドで使用される正規表現コンパイラは、その機能に非常に優れています。競争力のあるパフォーマンスのコードを手動で調整することは非常に困難です。

最後に、それらの存在は主に歴史的遺物です。彼らは長い間存在し、マインドシェアを獲得し、多くの人々が彼らを知っています。あなたが持っていて他の人がサポートできるツールは、まだ存在していない理論的なツールよりもはるかに優れています。

それがあなたをオフにする構文だけであるなら、多分あなたはHaskellのパーサーコンビネーターを見ることを検討するべきです。それらは同じアイデアのスーパーセットを表現でき、より明確な構文を持つことができます。

于 2008-11-05T16:09:42.247 に答える
4

それはその通りです...あなたが正しく指摘したように、主に伝統的な理由によるものです。今

  • 再トレーニングとツールの再構築: それは大きな支持を得ており、たとえ誰かが望んでいたとしても、そのルーツはオーバーホールするには深すぎます. 人々は難解なルールを学び、さまざまなトリック、コミュニティ、ツール (私は Expresso をプラグインします) を開発しました。
  • 広範なサポート: 現在の構文は、プラットフォーム間で広くサポートされています。独自のエンジンを作成し、すべての周辺ケースを処理するという記念碑的な作業を軽視したとしても、そのレベルのサポートを書き直すことは大きな作業です。
  • RegExp は変更される可能性が低い最後に、最も重要なこととして、RegExp はコードの可読性と同一視することはできません。個人的には、正規表現の利点が利点を上回る場合は、正規表現を控えめに、迅速な切開のために使用します。(たとえば、顧客の Excel スプレッドシートを開発者のために考案された XML 形式にスクレイピングするための内部ツール。) 正規表現を維持および変更する必要はありません。非常に複雑な場合は、コメントで臭いを隠します (および1 回だけにする必要があります)。正規表現が定期的に変更されている場合 (または、職場で誰も正規表現を知らない場合)、それはおそらく悪い選択であり、通常のコードに切り替える必要があります。

個人的には、正規表現 (少なくとも日常的なタスクに必要なセクション) を簡単に習得できると思います.. 1 日か 2 日です。

于 2008-11-05T04:36:03.910 に答える
3

あなたが言及した同様の質問とその回答を見てみると、今日私たちが知っている正規表現の支持者と批判者の両方から、「より使いやすい」代替構文を作成しようとする試みがいくつか見られました。

それらは同等の正規表現より一様に読みにくいことがわかりました。

確かに、私は正規表現の定期的なユーザーであるため、正規表現を快適に使用できることは、これの重要な部分であると確信しています。しかし、それらに関する私の主な問題は、慣れていないことではなく、すぐに大きくなりすぎて一度にすべてを受け入れることができなくなったことでした. 20 文字の正規表現が 10 行 x 30 列の疑似英語表現になると、その部分が互いにどのように関連しているかを確認することがはるかに難しくなります。

おそらく誰かが、複雑な場合でも普遍的に読みやすい正規表現の代替構文を考え出すでしょうが、そのような構文には本質的にサブルーチン呼び出しと同等のものが必要になると思います。ネストされたロジックの 15 レイヤーを含む 200 行のアプリケーション コード ブロックは記述しません。そのロジックを追跡するだけでも途方もない作業になるためです。正規表現をより英語に似た形式に分解しようとすると、同じ問題が発生し、それを管理するために同じツールが必要になります。

于 2008-11-05T15:57:21.460 に答える
2

アダムが言ったように、もっと良いものはありますか? 良い正規表現の代わりに、たくさんの strcmp 操作をしようと考えるとぞっとします。他の表現力豊かな言語と同様に、正規表現を悪用して非常に判読不能な構造を作成することは可能ですが、多くの場合、一見判読不能に見える正規表現でさえ、同じことを達成するための同等の手続き型コードよりもはるかに理にかなっています。

正規表現がなければ、独自のルーチンを作成して、インデックスの解析、バックトラック、比較、格納、置換、およびすべての結果の管理を行う必要があります。正規表現は、これらすべてを非常に表現力豊かな形式で提供します。私はコードを繰り返すのは好きではありませんが、適度に複雑なパターンを探す必要があるたびに独自のパーサーをコーディングする必要があるとしたら、どうしたらよいかわかりません。

はい、正規表現にはさまざまな種類がありますが、最も一般的な正規表現のほとんどは非常に似ており、通常、それらを使用している言語には、それを読むのに役立つドキュメントがあります.

于 2008-11-05T04:15:09.943 に答える
2

perl モジュールRegexp::Englishから:

Regexp::English は、代替の正規表現構文を提供します。これは、標準のメカニズムよりも少し冗長です。さらに、インクリメンタル エクスプレッション ビルディングやバウンド キャプチャなど、いくつかの便利な機能が追加されています。

    use Regexp::English;

    my $re = Regexp::English
            -> start_of_line
            -> literal('Flippers')
            -> literal(':')
            -> optional
                    -> whitespace_char
            -> end
            -> remember
                    -> multiple
                            -> digit;

    while (<INPUT>) {
            if (my $match = $re->match($_)) {
                    print "$match\n";
            }
    }
于 2012-05-31T04:14:32.570 に答える
0

この議論のすべての参加者は、特定の小さな正規表現コードについて、それが何をするかを説明する長い段落を英語で書かなければならないことに同意するでしょう。最も単純な正規表現でさえ説明することを行うために使用される可能性のある言語は、おそらくN行のコードでそれを行います.Nは(おそらく)正規表現自体の長さと比較して指数関数的に増加します.

于 2011-11-29T15:23:42.137 に答える