github.com/shogo82148/std@v1.22.1-0.20240327122250-4e474527810c/regexp/regexp.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package regexpは正規表現の検索を実装します。
     6  //
     7  // 受け入れる正規表現の構文は、Perl、Python、および他の言語で使用される一般的な構文です。
     8  // より正確には、RE2が受け入れる構文であり、以下で説明されています。
     9  // https://golang.org/s/re2syntax(\Cを除く)
    10  // 構文の概要については、 [regexp/syntax] パッケージを参照してください。
    11  //
    12  // このパッケージによって提供される正規表現の実装は、入力のサイズに比例して線形の時間で実行されることが保証されています。
    13  // (これは、ほとんどのオープンソースの正規表現の実装が保証していない特性です。)この特性の詳細については、次を参照してください。
    14  //
    15  // https://swtch.com/~rsc/regexp/regexp1.html
    16  //
    17  // またはオートマトン理論に関する書籍を参照してください。
    18  //
    19  // すべての文字はUTF-8でエンコードされたコードポイントです。
    20  // [utf8.DecodeRune] に従って、無効なUTF-8シーケンスの各バイトは、utf8.RuneError(U+FFFD)としてエンコードされたものとして扱われます。
    21  //
    22  // 正規表現に一致し、一致したテキストを識別する [Regexp] の16個のメソッドがあります。
    23  // これらのメソッドの名前は、次の正規表現と一致します。
    24  //
    25  // Find(All)?(String)?(Submatch)?(Index)?
    26  //
    27  // 'All'が存在する場合、このルーチンは表現全体の連続する重複しない一致を見つけます。直前の一致と隣接する空の一致は無視されます。戻り値は、対応する非-'All'ルーチンの連続する戻り値を含むスライスです。これらのルーチンは、追加の整数引数nを受け取ります。ただし、n >= 0の場合、関数は最大n個の一致/サブマッチを返し、それ以外の場合はすべてを返します。
    28  //
    29  // 'String'が存在する場合、引数は文字列です。それ以外の場合はバイトのスライスです。返り値は適切に調整されます。
    30  //
    31  // 'Submatch'が存在する場合、返り値は式の連続するサブマッチを識別するスライスです。サブマッチは、正規表現内のパレンセシスで囲まれたサブ式(キャプチャグループとも呼ばれる)の一致です。左から右にかけて開くかっこの順に番号が付けられています。サブマッチ0は式全体の一致であり、サブマッチ1は最初のカッコで囲まれた部分式の一致です。
    32  //
    33  // 'Index'が存在する場合、一致とサブマッチは入力文字列内のバイトインデックスのペアで識別されます。
    34  // result[2*n:2*n+2]はn番目のサブマッチのインデックスを識別します。n==0の場合のペアは、式全体の一致を識別します。'Index'が存在しない場合、一致/サブマッチのテキストで識別されます。
    35  // インデックスが負数であるか、テキストがnilの場合、サブ式は入力文字列内で一致するテキストがないことを意味します。
    36  // 'String'バージョンでは、空の文字列は一致がないか空の一致を意味します。
    37  //
    38  // RuneReaderから読み取られるテキストに適用できるメソッドのサブセットもあります:
    39  //
    40  // # MatchReader、FindReaderIndex、FindReaderSubmatchIndex
    41  //
    42  // このセットは増える可能性があります。正規表現の一致では、一致のために返されるテキストを超えたテキストを調べる必要がある場合があるため、RuneReaderからテキストを一致させるメソッドは、返される前に任意の深さまで入力を読み込む可能性があります。
    43  //
    44  // (このパターンに一致しないいくつかの他のメソッドもあります。)
    45  package regexp
    46  
    47  import (
    48  	"github.com/shogo82148/std/io"
    49  	"github.com/shogo82148/std/regexp/syntax"
    50  )
    51  
    52  // Regexpはコンパイルされた正規表現の表現です。
    53  // Regexpは [Regexp.Longest] などの構成方法を除いて、複数のゴルーチンによる並行利用に安全です。
    54  type Regexp struct {
    55  	expr           string
    56  	prog           *syntax.Prog
    57  	onepass        *onePassProg
    58  	numSubexp      int
    59  	maxBitStateLen int
    60  	subexpNames    []string
    61  	prefix         string
    62  	prefixBytes    []byte
    63  	prefixRune     rune
    64  	prefixEnd      uint32
    65  	mpool          int
    66  	matchcap       int
    67  	prefixComplete bool
    68  	cond           syntax.EmptyOp
    69  	minInputLen    int
    70  
    71  	// このフィールドは Longest メソッドによって変更可能ですが、それ以外では読み取り専用です。
    72  	longest bool
    73  }
    74  
    75  // Stringは正規表現をコンパイルするために使用されたソーステキストを返します。
    76  func (re *Regexp) String() string
    77  
    78  // Copyは、reからコピーされた新しい [Regexp] オブジェクトを返します。
    79  // コピーを使用して [Regexp.Longest] を呼び出しても他のコピーに影響を与えません。
    80  //
    81  // Deprecated: 以前のリリースでは、複数のゴルーチンで [Regexp] を使用する場合、
    82  // 各ゴルーチンに独自のコピーを与えることでロック競合を回避できました。
    83  // Go 1.12以降は、ロック競合を回避するためにCopyを使用する必要はありません。
    84  // Copyは、異なる [Regexp.Longest] 設定で2つのコピーを作成する必要がある場合には依然適切かもしれません。
    85  func (re *Regexp) Copy() *Regexp
    86  
    87  // Compileは正規表現をパースし、成功した場合には、
    88  // テキストと照合するために使用できる [Regexp] オブジェクトを返します。
    89  //
    90  // テキストと照合する際、正規表現は入力のなるべく早い位置(最も左端)から一致し、
    91  // その中からバックトラック検索が最初に見つけたものを選択します。
    92  // これを左端優先マッチングと呼びますが、
    93  // これはPerl、Pythonなどの実装と同じセマンティクスです。
    94  // ただし、このパッケージはバックトラックのコストなしで実装されています。
    95  // POSIXの左端最長一致マッチングについては、 [CompilePOSIX] を参照してください。
    96  func Compile(expr string) (*Regexp, error)
    97  
    98  // CompilePOSIXは [Compile] と同様ですが、正規表現をPOSIX ERE(egrep)構文に制限し、マッチのセマンティクスをleftmost-longestに変更します。
    99  // つまり、テキストに対してマッチングする際に、正規表現は入力(最も左側)で可能な限り早く開始するマッチを返し、その中でも可能な限り長いマッチを選択します。
   100  // このleftmost-longestマッチングと呼ばれる手法は、かつての正規表現の実装やPOSIXが指定するセマンティクスと同じです。
   101  // ただし、複数のleftmost-longestマッチが存在する場合、このパッケージはPOSIXとは異なる方法を採用します。
   102  // 可能なleftmost-longestマッチの中から、このパッケージはバックトラッキング検索で最初に見つかるマッチを選択します。一方、POSIXでは最初のサブエクスプレッション、次に2番目のサブエクスプレッション、以降左から右へと長さを最大化するマッチを選択すると規定されています。
   103  // POSIXのルールは計算上の制約があり、定義もされていません。
   104  // 詳細については、https://swtch.com/~rsc/regexp/regexp2.html#posixを参照してください。
   105  func CompilePOSIX(expr string) (*Regexp, error)
   106  
   107  // Longestは将来の検索において、最も左にある最長一致を優先します。
   108  // つまり、テキストに対して一致を探す場合、正規表現はできるだけ早く入力の最初に一致するものを返し、その中から最長の一致を選択します。
   109  // このメソッドは [Regexp] を修正するため、他のメソッドと同時に呼び出すことはできません。
   110  func (re *Regexp) Longest()
   111  
   112  // MustCompileは [Compile] と似ていますが、式を解析できない場合はパニックします。
   113  // これにより、コンパイルされた正規表現を保持するグローバル変数の安全な初期化が簡素化されます。
   114  func MustCompile(str string) *Regexp
   115  
   116  // MustCompilePOSIXは、 [CompilePOSIX] と似ていますが、式が解析できない場合にはpanicを発生させます。
   117  // これにより、コンパイルされた正規表現を保持するグローバル変数の安全な初期化を簡素化します。
   118  func MustCompilePOSIX(str string) *Regexp
   119  
   120  // NumSubexpはこの [Regexp] 内のカッコで囲まれたサブ式の数を返します。
   121  func (re *Regexp) NumSubexp() int
   122  
   123  // SubexpNamesはこの [Regexp] の括弧付きの部分式の名前を返します。
   124  // 最初の部分式の名前はnames[1]ですので、mがマッチスライスである場合、m[i]の名前はSubexpNames()[i]です。
   125  // 正規表現全体には名前を付けることができないため、names[0]は常に空の文字列です。
   126  // スライスは変更しないでください。
   127  func (re *Regexp) SubexpNames() []string
   128  
   129  // SubexpIndexは指定された名前を持つ最初のサブ式のインデックスを返します。
   130  // もし指定した名前のサブ式が存在しない場合は-1を返します。
   131  //
   132  // 複数のサブ式は同じ名前で書くこともできます。たとえば、(?P<bob>a+)(?P<bob>b+)のように、
   133  // "bob"という名前で2つのサブ式を宣言することができます。
   134  // この場合、SubexpIndexは正規表現内で最も左にあるサブ式のインデックスを返します。
   135  func (re *Regexp) SubexpIndex(name string) int
   136  
   137  // LiteralPrefixは、正規表現reの一致の開始部分である必要があるリテラル文字列を返します。もしリテラル文字列が正規表現全体を構成している場合、真を返します。
   138  func (re *Regexp) LiteralPrefix() (prefix string, complete bool)
   139  
   140  // MatchReaderは [io.RuneReader] が返すテキストに、正規表現reの一致が含まれているかどうかを報告します。
   141  func (re *Regexp) MatchReader(r io.RuneReader) bool
   142  
   143  // MatchStringは文字列sに正規表現reの一致があるかどうかを報告します。
   144  func (re *Regexp) MatchString(s string) bool
   145  
   146  // Matchは、バイトスライスbに正規表現reの一致が含まれているかどうかを報告します。
   147  func (re *Regexp) Match(b []byte) bool
   148  
   149  // MatchReaderは、RuneReaderによって返されるテキストに正規表現パターンの一致があるかどうかを報告します。
   150  // より複雑なクエリには [Compile] と完全な [Regexp] インターフェイスを使用する必要があります。
   151  func MatchReader(pattern string, r io.RuneReader) (matched bool, err error)
   152  
   153  // MatchStringは、文字列sが正規表現パターンに一致するものを含んでいるかどうかを報告します。
   154  // より複雑なクエリを行う場合は、 [Compile] と完全な [Regexp] インターフェースを使用する必要があります。
   155  func MatchString(pattern string, s string) (matched bool, err error)
   156  
   157  // Matchは、バイトスライス b が正規表現パターンのいずれかに一致するかどうかを報告します。
   158  // より複雑なクエリには、 [Compile] と完全な [Regexp] インターフェースを使用する必要があります。
   159  func Match(pattern string, b []byte) (matched bool, err error)
   160  
   161  // ReplaceAllStringは、srcの [Regexp] にマッチする箇所を置換文字列replで置き換えたsrcのコピーを返します。repl内では、 [Regexp.Expand] と同様に$記号が解釈されます。例えば、$1は最初のサブマッチのテキストを表します。
   162  func (re *Regexp) ReplaceAllString(src, repl string) string
   163  
   164  // ReplaceAllLiteralStringはsrcのコピーを返し、 [Regexp] の一致部分を置換文字列replで置き換えます。置換replは直接代入され、 [Regexp.Expand] を使用しません。
   165  func (re *Regexp) ReplaceAllLiteralString(src, repl string) string
   166  
   167  // ReplaceAllStringFuncは、srcのすべての [Regexp] の一致箇所を、関数replが適用された一致した部分文字列の返り値に置き換えたコピーを返します。replによって返される置換文字列は、 [Regexp.Expand] を使用せずに直接代入されます。
   168  func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string
   169  
   170  // ReplaceAllは、 [Regexp] の一致した箇所を置換テキストreplで置き換えたsrcのコピーを返します。repl内の$記号は [Regexp.Expand] と同様に解釈されます。つまり、$1は最初のサブマッチのテキストを表します。
   171  func (re *Regexp) ReplaceAll(src, repl []byte) []byte
   172  
   173  // ReplaceAllLiteralは、 [Regexp] の一致する箇所を置換バイトreplで置換したsrcのコピーを返します。置換replは、 [Regexp.Expand] を使用せずに直接代入されます。
   174  func (re *Regexp) ReplaceAllLiteral(src, repl []byte) []byte
   175  
   176  // ReplaceAllFuncは、 [Regexp] のすべての一致箇所を、
   177  // マッチしたバイトスライスに対して適用した関数replの戻り値で置換したsrcのコピーを返します。
   178  // replによって返される置換は、 [Regexp.Expand] を使用せずに直接代入されます。
   179  func (re *Regexp) ReplaceAllFunc(src []byte, repl func([]byte) []byte) []byte
   180  
   181  // QuoteMetaは、引数のテキスト内のすべての正規表現メタ文字をエスケープした文字列を返します。返された文字列は、リテラルテキストにマッチする正規表現です。
   182  func QuoteMeta(s string) string
   183  
   184  // Findは正規表現に一致する最も左側のテキストを含むスライスを返します。
   185  // nilの返り値は一致なしを示します。
   186  func (re *Regexp) Find(b []byte) []byte
   187  
   188  // FindIndexは、正規表現の一致する最も左側の箇所を示す整数の2要素スライスを返します。一致部分はb[loc[0]:loc[1]]にあります。
   189  // nilを返す場合は一致なしを示します。
   190  func (re *Regexp) FindIndex(b []byte) (loc []int)
   191  
   192  // FindStringは、正規表現の左端と一致する最初のテキストを保持する文字列を返します。
   193  // 一致がない場合、返り値は空の文字列になりますが、正規表現が空の文字列と一致する場合も同様に空になります。
   194  // これらのケースを区別する必要がある場合は、 [Regexp.FindStringIndex] または [Regexp.FindStringSubmatch] を使用してください。
   195  func (re *Regexp) FindString(s string) string
   196  
   197  // FindStringIndexは、正規表現のsにおける最も左にマッチする部分の位置を定義する、整数の2要素のスライスを返します。マッチはs[loc[0]:loc[1]]にあります。
   198  // nilの返り値は、マッチが見つからなかったことを示します。
   199  func (re *Regexp) FindStringIndex(s string) (loc []int)
   200  
   201  // FindReaderIndexは、 [io.RuneReader] から読み込まれたテキスト内で正規表現の最左一致の位置を示す整数の2要素スライスを返します。マッチしたテキストは、入力ストリームのバイトオフセットloc[0]からloc[1]-1までで見つかりました。
   202  // nilの戻り値は一致がないことを示します。
   203  func (re *Regexp) FindReaderIndex(r io.RuneReader) (loc []int)
   204  
   205  // FindSubmatchは、正規表現でb内で最も左にマッチするテキストと、そのサブエクスプレッション('Submatch'のパッケージの説明による)のマッチ(あれば)を保持するスライスのスライスを返します。
   206  // nilの戻り値は、マッチがないことを示します。
   207  func (re *Regexp) FindSubmatch(b []byte) [][]byte
   208  
   209  // Expandはテンプレートをdstに追加し、結果を返します。追加の過程で、Expandはテンプレート内の変数をsrcから引っ張った対応する一致で置き換えます。一致スライスは [Regexp.FindSubmatchIndex] によって返されるべきです。
   210  //
   211  // テンプレート中では、変数は$nameまたは${name}の形式の部分文字列で示されます。nameは非空の文字、数字、アンダースコアの連続です。$1のような純粋な数字の名前は、対応するインデックスのサブマッチを参照します。その他の名前は、(?P<name>...)構文で名前付きのキャプチャ括弧を参照します。範囲外またはマッチしないインデックスの参照または正規表現に存在しない名前は、空のスライスで置き換えられます。
   212  //
   213  // $name形式では、nameは可能な限り長くなります:$1xは${1x}ではなく${1}xと等価です。また、$10は${10}ではなく${1}0と等価です。
   214  // 出力にリテラルの$を挿入するには、テンプレートで$$を使用してください。
   215  func (re *Regexp) Expand(dst []byte, template []byte, src []byte, match []int) []byte
   216  
   217  // ExpandStringは、 [Regexp.Expand] と同様にテンプレートとソースが文字列の場合に使用します。
   218  // 割り当てに対する制御を呼び出し元のコードに提供するために、バイトスライスに追加して返します。
   219  func (re *Regexp) ExpandString(dst []byte, template string, src string, match []int) []byte
   220  
   221  // FindSubmatchIndexは、正規表現の最も左側の一致と、'Submatch'および'Index'の説明で定義される、必要に応じてそのサブ式のマッチを示すインデックスのペアを保持するスライスを返します。
   222  // nilの返り値は、一致が見つからないことを示します。
   223  func (re *Regexp) FindSubmatchIndex(b []byte) []int
   224  
   225  // FindStringSubmatchは、正規表現の最も左にマッチするテキストと、そのサブエクスプレッションにマッチするテキスト(あれば)を保持する文字列のスライスを返します。パッケージのコメントにある'Submatch'の説明によって定義されます。
   226  // nilの返り値は、マッチがないことを示します。
   227  func (re *Regexp) FindStringSubmatch(s string) []string
   228  
   229  // FindStringSubmatchIndexは、正規表現の最も左にある一致と、
   230  // パッケージコメントで定義された'Submatch'および'Index'の説明によって決まる、
   231  // サブ式の一致(ある場合)を特定するインデックスのペアを保持するスライスを返します。
   232  // nilの返り値は一致なしを示します。
   233  func (re *Regexp) FindStringSubmatchIndex(s string) []int
   234  
   235  // FindReaderSubmatchIndexは、 [io.RuneReader] によって読み取られたテキストの正規表現の最も左の一致と、そのサブエクスプレッションの一致(ある場合)を識別するインデックスのペアを保持するスライスを返します。パッケージコメントの'Submatch'と'Index'の説明で定義されています。nilの返り値は一致がないことを示します。
   236  func (re *Regexp) FindReaderSubmatchIndex(r io.RuneReader) []int
   237  
   238  // FindAllは [Regexp.Find] の 'All' バージョンであり、パッケージコメントで定義されている 'All' の説明に従って、
   239  // 式の全ての連続するマッチのスライスを返します。
   240  // nilの返り値はマッチがないことを示します。
   241  func (re *Regexp) FindAll(b []byte, n int) [][]byte
   242  
   243  // FindAllIndexは [Regexp.FindIndex] の「All」バージョンであり、
   244  // パッケージコメントで定義されている「All」の説明に従って、
   245  // 式のすべての連続する一致のスライスを返します。
   246  // nilの返り値は一致がないことを示します。
   247  func (re *Regexp) FindAllIndex(b []byte, n int) [][]int
   248  
   249  // FindAllStringは [Regexp.FindString] の'All'バージョンです。式によって定義されるように、
   250  // 'All'の説明に従って、連続する全ての一致する部分文字列のスライスを返します。
   251  // nilの返り値は一致なしを示します。
   252  func (re *Regexp) FindAllString(s string, n int) []string
   253  
   254  // FindAllStringIndexは [Regexp.FindStringIndex] の「All」バージョンです。式によって定義されるすべての連続したマッチのスライスを返します。「All」の説明によってパッケージのコメントで定義されます。
   255  // nilの返り値はマッチがないことを示します。
   256  func (re *Regexp) FindAllStringIndex(s string, n int) [][]int
   257  
   258  // FindAllSubmatchは、 [Regexp.FindSubmatch] の 'All' バージョンです。この関数は、'All' 説明によって定義された通り、式に連続するすべての一致部分をスライスとして返します。
   259  // nilの返り値は、マッチが見つからなかったことを示します。
   260  func (re *Regexp) FindAllSubmatch(b []byte, n int) [][][]byte
   261  
   262  // FindAllSubmatchIndexはFindSubmatchIndexの'All'バージョンであり、
   263  // パッケージコメントの'All'の説明に従って、式に対するすべての連続した一致結果のスライスを返します。
   264  // nilの返り値は一致なしを示します。
   265  func (re *Regexp) FindAllSubmatchIndex(b []byte, n int) [][]int
   266  
   267  // FindAllStringSubmatchは、 [Regexp.FindSubmatchIndex] の「All」バージョンであり、式によって定義されたすべての連続した一致のスライスを返します。パッケージコメントの「All」の説明に従います。
   268  // nilの戻り値は一致がないことを示します。
   269  func (re *Regexp) FindAllStringSubmatch(s string, n int) [][]string
   270  
   271  // FindAllStringSubmatchIndexは [Regexp.FindStringSubmatchIndex] の「All」バージョンであり、
   272  // 式によって定義されるすべての連続した一致のスライスを返します。
   273  // パッケージコメントの「All」の説明で定義されているように、
   274  // nilの戻り値は一致がないことを示します。
   275  func (re *Regexp) FindAllStringSubmatchIndex(s string, n int) [][]int
   276  
   277  // Splitメソッドは、文字列sを指定の表現によって区切り、それらの表現にマッチする部分文字列のスライスを返します。
   278  //
   279  // このメソッドによって返されるスライスは、sのうちFindAllStringで返されるスライスに含まれていない
   280  // 全ての部分文字列からなります。メタ文字を含まない表現に対しては、 [strings.SplitN] と同等の動作になります。
   281  //
   282  // 例:
   283  //
   284  //	s := regexp.MustCompile("a*").Split("abaabaccadaaae", 5)
   285  //	// s: ["", "b", "b", "c", "cadaaae"]
   286  //
   287  // countパラメータによって返す部分文字列の数が決まります:
   288  //
   289  //	n > 0: 最大でn個の部分文字列を返します。最後の部分文字列は分割されなかった残りの部分です。
   290  //	n == 0: 結果はnil(部分文字列なし)です。
   291  //	n < 0: 全ての部分文字列を返します。
   292  func (re *Regexp) Split(s string, n int) []string
   293  
   294  // MarshalTextは[encoding.TextMarshaler]を実装します。出力は
   295  // [Regexp.String]メソッドを呼び出した場合と一致します。
   296  //
   297  // 注意:このメソッドはいくつかの場合において情報の損失があります。POSIX
   298  // 正規表現(つまり、[CompilePOSIX]を呼び出してコンパイルされたもの)や、
   299  // [Regexp.Longest]メソッドが呼び出された正規表現については示しません。
   300  func (re *Regexp) MarshalText() ([]byte, error)
   301  
   302  // UnmarshalTextは、エンコードされた値に対して[Compile]を呼び出すことで、[encoding.TextUnmarshaler]を実装します。
   303  func (re *Regexp) UnmarshalText(text []byte) error