web-dev-qa-db-ja.com

正規表現にコメントする

正規表現にコメントするための一般的な方法はありますか:正規表現の異なる部分を参照するインラインコメントまたはすべての表現に対する一般的なコメント?

11
m0nhawk

私の見解では、正規表現の一般的な考え方が何であるかをコメントで簡潔に述べることをお勧めします。これにより、他の開発者(または時には自分自身)が RegExr のようなパーサーに正規表現をコピーして貼り付ける手間が省けます。

10
pleinolijf

これはいくぶん言語固有の答えですが、質問には言語が記載されていません。

"Dive Into Python" は、Verbose Regular Expressionsを使用してコメントを実装することを提案しています:

Pythonでは、詳細な正規表現と呼ばれるものでこれを行うことができます。詳細な正規表現は、次の2つの点でコンパクトな正規表現とは異なります。

  • 空白は無視されます。スペース、タブ、およびキャリッジリターンは、スペース、タブ、およびキャリッジリターンとは一致しません。それらはまったく一致していません。 (詳細な正規表現のスペースに一致させる場合は、その前にバックスラッシュを挿入してエスケープする必要があります。)
  • コメントは無視されます。詳細な正規表現のコメントは、Pythonコードのコメントと同じです:#文字で始まり、行の終わりまで続きます。この場合はコメントです。ソースコード内ではなく複数行の文字列内ですが、同じように機能します。

例:

>>> pattern = """
^                   # beginning of string
M{0,4}              # thousands - 0 to 4 M's
(CM|CD|D?C{0,3})    # hundreds - 900 (CM), 400 (CD), 0-300 (0 to 3 C's),
                    #            or 500-800 (D, followed by 0 to 3 C's)
(XC|XL|L?X{0,3})    # tens - 90 (XC), 40 (XL), 0-30 (0 to 3 X's),
                    #        or 50-80 (L, followed by 0 to 3 X's)
(IX|IV|V?I{0,3})    # ones - 9 (IX), 4 (IV), 0-3 (0 to 3 I's),
                    #        or 5-8 (V, followed by 0 to 3 I's)
$                   # end of string
"""
>>> re.search(pattern, 'M', re.VERBOSE)                1

ソースと詳細 ここ

この方法には、パターンが詳細形式で記述されていることを呼び出し側が認識し、それに応じて呼び出す必要があるというわずかな欠点があります。

9
Rotem

通常、私は正規表現を作成し、個々の正規表現について説明するのではなく、その目的を説明します。それがその理由と理由です。これは、「私のコメントはどのように見えるべきですか?」誰が言うだろう」コードが何をしているかを書くのではなく、なぜコードが何をしているかを書く

// Strip the leading "?" and remove the query parameters "offset=<integer>" & "count=<integer> so we have a pattern of the request"          
var search = location.search.substring(1).replace(/offset=[0-9]+?&/g, "").replace(/count=[0-9]+?&/g, "");

コード内のコメントを介して正規表現について誰かに教えようとしているのでない限り、個々の部分が何をするのかを説明することは考えていません。他のプログラマーと一緒に作業するときは、グローバルな正規表現として何かを知っていると想定しても問題ありません。

8
user7007

それは本当にあなたが正規表現をどのように組み合わせているかに依存すると思います。一般的に言って、実際の正規表現文字列自体の中にコメントを入れるのは悪い考えだと思います(私の知る限り、ほとんどのシナリオでは不可能です)。正規表現の特定の部分に本当にコメントする必要がある場合(誰かに教えるつもりですか?)、各チャンクを独自の行で別々の文字列に分割し、プログラミング言語の通常のコメントプロセスを使用して各行にコメントを付けます。そうでなければ、pleinolijfの答えはかなり良いです。

例:

string myregex = "\s" // Match any whitespace once
+ "\n"  // Match one newline character
+ "[a-zA-Z]";  // Match any letter
6
Matt

私は通常、名前が正規表現の全体的な目的を表す文字列定数を定義します。

例えば:

const string FloatingPointNumberPattern = @"[-+]?[0-9]*\.?[0-9]+";

この定数の上にコメントを追加して説明を付けることもできますが、通常は定数名自体で十分です。

4
Bernard

一部のシナリオでは、開発者が正規表現を使用して、通常のドメイン外のテキストを照合している場合があります。元の開発者は、その反復プロセスによってのみ発見された可能性のあるさまざまなEdgeケースをキャプチャする多くの反復を経験した可能性があります。したがって、後続の開発者は、一般的なケースを認識していても、元の開発者が処理したEdgeケースの多くを認識していない可能性があります。

このような場合、バリエーションの例を文書化することは価値があります。このドキュメントの場所は、量によって異なる場合があります(たとえば、必ずしもコード内である必要はありません)。

これに取り組む1つの方法は、将来の開発者は正規表現の仕組みなどの基本的な知識しか持たず、(1)正規表現を開発する前に知っていた知識が必ずしも必要ではないと想定することです。将来の開発者、または(2)開発中に得た知識(たとえば、発見されたEdgeケース)。

たとえば、開発中に「ああ、私はXがこの形式をとることができることを知りませんでした」と言った場合、それを文書化する価値があります(おそらく、そのバリエーションを処理する正規表現の一部)。

3
bstovall

コメントには、コードからは明らかではない有用な情報を追加する必要があります。

  1. コード自体またはコメントのいずれかで、式が要件レベルで何をするかを理解しやすくします。この表現の目的は、電子メールアドレスを検証したり、カナダの電話番号を調べたりすることです。
  2. 式が実際に何をしているのか、つまり式の評価結果を簡単に理解できるようにします。最初に式を分割して明確にすることを試みます。最初にすべてのハイフンを確認してからすべての数値を削除し、中間値を保持する変数を含む2つの部分からなる式を作成すると、非常に読みやすくなり、リーダーはロジックを1つずつステップ実行できます。 (SEでの質問に対する有名な回答があります。ビット操作 '>>'を含む古いコードを誰かが解読しようとしているため、特定のフラグが設定されていて、コードが実際に何を行っているかだけでなく、どのように回答しているかがわかります。質問のauthourは、将来この種のコードを分解することになるはずです。これはまさに私が説明しようとしていることですが、リンクする質問を見つけることができないようです)

最後のサイクルごとに必要なアプリケーションはほとんどありません。大量のデータセットをパターンマッチングする場合は、より良い方法があるかもしれませんが、そうでない場合もありますが、ほとんどの場合、余分な実行時間はそれほど大きな問題ではありません。

そして、コードを見つけてバグを修正する次の人が6か月後にあなたである可能性があることを覚えておいてください。

2
Encaitar

RegExを別のクラスに、意味のある名前でに抽出します。次に、自動テストでコードを文書化します。

これにより、

  • コードが実際に機能すること-コーナーケースでも
  • 迅速な「バグ修正」が多くのコーナーケースを台無しにしないことを保証します
  • バックトラッキングが無効になっている最適化を文書化できます

当然、クラスはいくつかの正規表現をホストする場合があります。

1
Carlo V. Dango