43

ワームの缶を開けて反対票を得る危険を冒して、私は自分自身に尋ねる必要があることに気づきました、

どのような場合に正規表現を使用する必要があり、どのような場合に文字列解析を使用する方が適切ですか?

そして、あなたのスタンスに関する理由が必要になります。readabilitymaintainabilityscaling、そしておそらくあなたの答えのほとんどすべてのパフォーマンスなどに対処していただきたいと思います。

ここで別の質問を見つけましたが、例を挙げても答えが1つしかありませんでした。これを理解するにはもっと必要です。

私は現在C++で遊んでいますが、正規表現はほぼすべての高水準言語にあり、さまざまな言語が正規表現をどのように使用/処理するかを知りたいのですが、それは後で考えました.

それを理解するのを手伝ってくれてありがとう!

編集: 私はまだより多くの例を探しており、これについて話していますが、これまでの反応は素晴らしいものでした. :)

4

2 に答える 2

39

扱っている言語がどれほど複雑かによって異なります。

分割

これは機能する場合に優れていますが、エスケープ規則がない場合にのみ機能します。たとえば、引用符で囲まれた文字列内のコンマは適切な分割ポイントではないため、CSV では機能しません。

フー、バー、バズ

分割できますが、

フー、「バー、バズ」

できません。

通常

正規表現は、「正規文法」を持つ単純な言語に最適です。Perl 5 の正規表現は、後方参照のためにもう少し強力ですが、一般的な経験則は次のとおりです。

(...)ブラケット ( , ) または HTML タグのような他のネストに一致させる必要がある場合[...]、正規表現だけでは十分ではありません。

正規表現を使用して、文字列を既知の数のチャンクに分割できます。たとえば、日付から月/日/年を抽出できます。ただし、複雑な算術式を解析するのは間違った仕事です。

当然のことながら、正規表現を書き、コーヒーを飲みに立ち去り、戻ってきて、書いた内容を簡単に理解できない場合は、自分が行っていることをより明確に表現する方法を探す必要があります。 電子メール アドレスは、正規表現を使用して正しく読みやすく処理できる限界に達している可能性があります。

文脈自由

パーサー ジェネレーターと手動でコーディングされたプッシュダウン/PEG パーサーは、ネストを処理する必要があるより複雑な入力を処理するのに最適です。これにより、ツリーを構築したり、演算子の優先順位や結合性を処理したりできます。

コンテキストフリーパーサーは、多くの場合、正規表現を使用して最初に入力をチャンク (スペース、識別子、句読点、引用符で囲まれた文字列) に分割し、次に文法を使用してそのチャンクのストリームをツリー形式に変換します。

CF 文法の経験則は次のとおりです。

正規表現が不十分で、言語内のすべての単語が事前の宣言に関係なく同じ意味を持つ場合、CF は機能します。

非文脈自由

言語の単語が文脈によって意味が変わる場合は、より複雑な解決策が必要です。これらはほとんどの場合、手作業でコーディングされたソリューションです。

たとえば、C では、

#ifdef X
  typedef int foo
#endif

foo * bar

fooが型の場合、 はという名前のポインタfoo * barの宣言です。それ以外の場合は、 という名前の変数によって名前が付けられた変数の乗算です。foobarfoobar

于 2012-08-10T16:51:51.067 に答える
9

正規表現と文字列の解析である必要があります..

どちらも有利に使用できます!多くの場合、プログラマーはテキストを解析するために単一の正規表現を作成しようとしますが、それを維持するのが非常に難しいと感じます..必要に応じて両方を使用する必要があります.

REGEX エンジンは高速です単純な照合には 1 マイクロ秒もかかりませんが、HTML の解析にはお勧めできません。

于 2012-08-10T16:44:47.763 に答える