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