Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 18932] ファイルの概要

このコミットは、Go言語の正規表現エンジンにおけるregexp/syntaxパッケージのドキュメントを更新し、x{n}のような繰り返し指定子におけるnの上限が1000であることを明記するものです。これにより、ユーザーが予期せぬエラーに遭遇するのを防ぎ、正規表現の挙動に関する明確なガイドラインを提供します。

コミット

commit 929ee59fce2a314a28a25629e6c99402ec97603e
Author: Rob Pike <r@golang.org>
Date:   Tue Mar 25 11:19:25 2014 +1100

    regexp/syntax: document the upper limit of n in x{n}
    Fixes #7252.
    
    LGTM=rsc
    R=rsc
    CC=golang-codereviews
    https://golang.org/cl/77990044

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/929ee59fce2a314a28a25629e6c99402ec97603e

元コミット内容

このコミットは、Go言語の標準ライブラリに含まれる正規表現パッケージregexpの低レベルな構文解析を担当するregexp/syntaxパッケージのドキュメントを修正するものです。具体的には、正規表現の繰り返し指定子であるx{n}xn回繰り返されることを意味する)において、nの値に実装上の上限が存在することを明記しています。この変更は、Issue 7252を解決するために行われました。

変更の背景

Go言語の正規表現エンジンは、効率性と堅牢性を重視して設計されています。正規表現の繰り返し指定子、特にx{n}のような固定回数の繰り返しは、非常に大きなnの値が指定された場合に、内部的なデータ構造や処理に過度な負荷をかける可能性があります。また、負の数を指定するなどの不正な使用も考えられます。

このコミットが行われた背景には、おそらくユーザーがx{n}形式の繰り返し指定子で、非常に大きな数値や無効な数値を指定した際に、予期せぬ挙動やエラーに遭遇したという問題(Issue 7252)があったと考えられます。Goの正規表現エンジンは、このような極端なケースに対して内部的な制限を設けていましたが、その制限がドキュメントに明記されていなかったため、ユーザーが混乱する可能性がありました。

このコミットは、既存の実装上の制限(nの上限が1000であること、および負の数や上限を超える数が指定された場合にErrInvalidRepeatSizeというパースエラーが発生すること)を明確にドキュメントに追加することで、ユーザーが正規表現を記述する際の混乱を解消し、より予測可能な挙動を提供することを目的としています。これにより、開発者は正規表現の記述において、この制限を考慮に入れることができるようになります。

前提知識の解説

正規表現 (Regular Expression)

正規表現は、文字列のパターンを記述するための強力なツールです。特定の文字列の検索、置換、抽出などに広く用いられます。多くのプログラミング言語やテキストエディタでサポートされており、Go言語も標準ライブラリで正規表現をサポートしています。

繰り返し指定子 (Quantifiers)

正規表現には、直前の要素が何回繰り返されるかを指定する「繰り返し指定子(Quantifiers)」があります。

  • x*: xが0回以上繰り返される
  • x+: xが1回以上繰り返される
  • x?: xが0回または1回繰り返される
  • x{n}: xが厳密にn回繰り返される
  • x{n,}: xn回以上繰り返される
  • x{n,m}: xn回以上m回以下繰り返される

本コミットで言及されているのは、x{n}x{n,}x{n,m}のような、繰り返し回数を数値で指定する形式です。

Go言語の regexp および regexp/syntax パッケージ

Go言語には、正規表現を扱うためのregexpパッケージが標準で提供されています。このパッケージは、正規表現のコンパイル、マッチング、検索、置換などの高レベルな機能を提供します。

regexp/syntaxパッケージは、regexpパッケージの内部で利用される低レベルなパッケージです。その主な役割は以下の通りです。

  1. 正規表現のパース: 正規表現の文字列を解析し、抽象構文木(AST: Abstract Syntax Tree)に変換します。このASTは、正規表現の構造をプログラムが理解しやすい形式で表現したものです。
  2. 正規表現のコンパイル: パースされた抽象構文木を、正規表現エンジンが実行可能なバイトコードのような内部表現(プログラム)にコンパイルします。

つまり、regexp/syntaxパッケージは、正規表現の「意味」を解釈し、それを実行可能な形式に変換する役割を担っています。このコミットは、このパース段階での特定の繰り返し指定子に対する制限をドキュメントに追加するものです。

ErrInvalidRepeatSize

これは、regexp/syntaxパッケージが正規表現をパースする際に発生する可能性のあるエラーの一つです。繰り返し指定子(例: x{n})において、nの値が不正(例えば、負の数や、実装上の上限を超える数)である場合にこのエラーが返されます。

技術的詳細

このコミットは、regexp/syntaxパッケージのdoc.goファイルに、繰り返し指定子に関する重要な実装上の制限を追記しています。具体的には、以下の記述が追加されました。

+Implementation restriction: The counting forms x{n} etc. (but not the other
+forms x* etc.) have an upper limit of n=1000. Negative or higher explicit
+counts yield the parse error ErrInvalidRepeatSize.

この記述が意味する技術的な詳細は以下の通りです。

  1. 対象となる繰り返し指定子: この制限は、x{n}x{n,}x{n,m}のように、明示的に繰り返し回数を数値で指定する形式にのみ適用されます。x*(0回以上)、x+(1回以上)、x?(0回または1回)のような、回数を指定しない形式には適用されません。これらの形式は、内部的に異なる方法で処理されるため、数値による上限の制約を受けません。

  2. nの上限: x{n}形式におけるnの値は、最大で1000までという上限が設けられています。これは、正規表現エンジンの内部的な効率性やリソース消費を考慮した実装上の制約です。非常に大きな繰り返し回数を指定すると、正規表現エンジンの状態管理が複雑になったり、メモリ消費が増大したりする可能性があります。1000という値は、一般的なユースケースをカバーしつつ、過度なリソース消費を防ぐためのバランス点として設定されたと考えられます。

  3. エラー挙動: nに負の数を指定した場合、または1000を超える数を指定した場合、正規表現のパース時にErrInvalidRepeatSizeというエラーが発生します。これは、正規表現が不正な構文として扱われることを意味します。このエラーは、正規表現のコンパイル時(regexp.Compile関数など)に返されるため、実行時に予期せぬパニックや誤動作を引き起こすのではなく、開発段階で問題が検出されるようになっています。

このドキュメントの追加により、Goの正規表現エンジンがどのように動作するかについて、より明確な情報が提供され、開発者が正規表現を記述する際の誤解やエラーを減らすことができます。

コアとなるコードの変更箇所

変更はsrc/pkg/regexp/syntax/doc.goファイルに対して行われました。

--- a/src/pkg/regexp/syntax/doc.go
+++ b/src/pkg/regexp/syntax/doc.go
@@ -46,6 +46,10 @@ Repetitions:
   x{n,}?         n or more x, prefer fewer
   x{n}?          exactly n x
  
+Implementation restriction: The counting forms x{n} etc. (but not the other
+forms x* etc.) have an upper limit of n=1000. Negative or higher explicit
+counts yield the parse error ErrInvalidRepeatSize.
+
 Grouping:
   (re)           numbered capturing group (submatch)
   (?P<name>re)   named & numbered capturing group (submatch)

コアとなるコードの解説

この変更は、既存の正規表現の繰り返し指定子に関する説明の直後に、新しい4行のコメントを追加するものです。

追加されたコメントは以下の通りです。

+Implementation restriction: The counting forms x{n} etc. (but not the other
+forms x* etc.) have an upper limit of n=1000. Negative or higher explicit
+counts yield the parse error ErrInvalidRepeatSize.

このコメントは、regexp/syntaxパッケージが正規表現を解析する際に適用される、x{n}形式の繰り返し指定子に関する重要な実装上の制約を明確に記述しています。

  • Implementation restriction:: これは、Goの正規表現エンジンの内部的な実装に起因する制約であることを示しています。
  • The counting forms x{n} etc. (but not the other forms x* etc.): この制限が適用されるのは、x{n}x{n,}x{n,m}のように、繰り返し回数を数値で指定する形式のみであることを強調しています。x*x+x?のような、数値で回数を指定しない形式は対象外です。
  • have an upper limit of n=1000.: nの値が1000という上限を持つことを明記しています。
  • Negative or higher explicit counts yield the parse error ErrInvalidRepeatSize.: nに負の数を指定した場合、または1000を超える数を指定した場合に、ErrInvalidRepeatSizeというパースエラーが発生することを説明しています。これにより、ユーザーは不正な正規表現を記述した場合に、どのようなエラーが返されるかを事前に知ることができます。

この追加により、regexp/syntaxパッケージのドキュメントはより完全になり、開発者がGoの正規表現をより正確に理解し、適切に利用するための重要な情報が提供されました。

関連リンク

参考にした情報源リンク

  • Go言語の公式ドキュメント (go.dev)
  • GitHubのgolang/goリポジトリ
  • 正規表現に関する一般的な知識