0

他の誰かが書いた正規表現の行を修正するように依頼されました。この式は、URL の一致をチェックするために使用されます。これは非常に長く、100 文字を超えており、十分に文書化されていません。このような問題に対処するための秘訣や近道はありますか?

次のようになります。

/^(([\w]+:)?\/\/)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(\/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$/
4

5 に答える 5

3

YAPE::Regex::Explainを使ってこれをやってみてください:

perl -MYAPE::Regex::Explain -e '
    my $regex = "/^...$/";
    print YAPE::Regex::Explain->new($regex)->explain;
'

サンプル出力

The regular expression:



matches as follows:

NODE                     EXPLANATION
----------------------------------------------------------------------
(?-imsx:                 group, but do not capture (case-sensitive)
                         (with ^ and $ matching normally) (with . not
                         matching \n) (matching whitespace and #
                         normally):
----------------------------------------------------------------------
  /                        '/'
----------------------------------------------------------------------
  ^                        the beginning of the string
----------------------------------------------------------------------
  (                        group and capture to \1 (optional
                           (matching the most amount possible)):
----------------------------------------------------------------------
    (                        group and capture to \2 (optional
                             (matching the most amount possible)):
----------------------------------------------------------------------
(...)

この投稿も参照してください: https://stackoverflow.com/questions/772594/regular-expression-explained-with-words

于 2013-02-25T21:15:26.717 に答える
2

複数の行に分割し、1 つずつ把握します。これを行う方法がわからない場合は、グループ、繰り返し、代替、および文字クラスがどのように機能するかを理解するために、正規表現の構文をさらに学習する必要があります。

これらの部分が何であるかを確認するのに役立つ Web サイトがいくつかあります。たとえば、http://regexr.com で入力した正規表現にマウスを合わせると、その部分だけが強調表示されて説明されているのを確認したり、http://regexpalに配置したりできます。 .comを開き、正規表現全体をさまざまな色で強調表示します。

正規表現をより管理しやすいチャンクに分割する方法は次のとおりです。

^
(
  ([\w]+:)?
  \/\/
)?
(
  (
    [\d\w]
    |
    %[a-fA-f\d]{2,2}
  )+
  (
    :
    (
      [\d\w]
      |
      %[a-fA-f\d]{2,2}
    )+
  )?
  @
)?
(
  [\d\w][-\d\w]{0,253}[\d\w]\.
)+
[\w]{2,4}
(:[\d]+)?
(
  \/
  (
    [-+_~.\d\w]
    |
    %[a-fA-f\d]{2,2}
  )*
)*
(
  \?
  (
    &?
    (
      [-+_~.\d\w]
      |
      %[a-fA-f\d]{2,2}
    )
    =?
  )*
)?
(
  #
  (
    [-+_~.\d\w]
    |
    %[a-fA-f\d]{2,2}
  )*
)?
$

これらすべての要素が何を意味するのかを実際に調べる時間はありませんが、URL を検証するためのもののように思えます。

于 2013-02-25T20:51:26.547 に答える
2
  1. 正規表現の構文を知っている。

    sputnick の回答は、構文の意味を学習する 1 つの方法を示しています。正規表現を分析し、トークンの意味を説明する正規表現テスト Web サイトも多数あります。

    詳細については、チュートリアル、または使用している言語の正規表現のドキュメントを参照することもできます。(言語間の正規表現の実装にはあちこちでわずかな違いがあるため、適切な言語のドキュメントを読むことが重要です)。

  2. コンテキスト/ドメインの知識を収集します。

    正規表現が書かれている理由、または正規表現が何のために使用されることを意図しているかを探してください。これは通常、コメントまたは関数名に反映されます。たとえば、eval関数に入れる前に正規表現を使用して入力をクリーンアップする場合、いくつかの攻撃ベクトルを考えて、正規表現が攻撃を中和するために何かを行うかどうかを確認できます。

    あなたの場合、それは一致する URL であるため、Wikipedia で検索し、URL に関連する RFC を参照して、BNF 文法を探すことができます。それが最良のケースですが、それがなくても、正規表現に/or ?or#が現れることをすでに期待しているかもしれません。

  3. 分割統治

    正規表現を「RAW」形式に変換する必要があります。たとえば、正規表現が文字列で指定されている場合、いくつかの特殊文字で追加のエスケープを行う必要があります。最初のステップでは、そのプロセスを逆にします。あなたの場合、あなたが持っている正規表現は/区切り文字として使用しているため、で行われたエスケープを元に戻す必要があります/

    ^(([\w]+:)?//)?(([\d\w]|%[a-fA-f\d]{2,2})+(:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}(:[\d]+)?(/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*(\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?(#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?$
    

    ドメインの知識と正規表現の構文に基づいて、正規表現を大きなフラグメントに分割します。

    ^
    (([\w]+:)?//)?
    (([\d\w]|%[a-fA-f\d]{2,2})+
    (:([\d\w]|%[a-fA-f\d]{2,2})+)?@)?
    ([\d\w][-\d\w]{0,253}[\d\w]\.)+[\w]{2,4}
    (:[\d]+)?
    (/([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)*
    (\?(&?([-+_~.\d\w]|%[a-fA-f\d]{2,2})=?)*)?
    (#([-+_~.\d\w]|%[a-fA-f\d]{2,2})*)?
    $
    

    と で始まる部分は?#それぞれクエリとフラグメントであると推測できます。/singleは path にのみ属することができると推測することもできます。また、互いに近い部分がスキームである可能性が高い:と推測できます。//そして@、ユーザー名とパスワードの部分と関係があることを示します。上記の推測で、上記の少なくとも半分に到達できます。

    別のヒューリスティックは、正規表現を「トップレベル」のトークン (抽象構文ツリーの「トップレベル」) に分割することです。通常、単一またはいくつかの「トップレベル」トークンの組み合わせが、一致するテキスト内の意味のある部分に対応します。

    正規表現を大きなフラグメントに分割したため、一致させようとしているテキストの対応する部分への正規表現フラグメントの明確なマッピングがあれば、各フラグメントを個別に処理できます。

于 2013-02-25T22:27:41.000 に答える
0

それを視覚化ツールにフィードします。Regexperのようなものは、何が起こっているかについてのビューを提供します。

この場合、URIを解析するための正規表現があるようです。それを考えると、一般的に、入力文字列をURIパーサーにフィードし、代わりにハードワークを実行させる方がはるかに優れています。すべてのメリットが得られ、オブジェクトを1つずつ操作することもできます。

于 2013-02-25T22:35:58.257 に答える
0

debuggexで視覚化できます。路線図が表示され、正規表現内で何が起こっているかを正確に確認するためにステップバイステップで実行できるサンプル マッチが提供されます。

于 2013-02-27T06:16:52.750 に答える