Source File
regexp.go
Belonging Package
regexp
package regexp
import (
)
type Regexp struct {
expr string // as passed to Compile
prog *syntax.Prog // compiled program
onepass *onePassProg // onepass program or nil
numSubexp int
maxBitStateLen int
subexpNames []string
prefix string // required prefix in unanchored matches
prefixBytes []byte // prefix, as a []byte
prefixRune rune // first rune in prefix
prefixEnd uint32 // pc for last rune in prefix
mpool int // pool for machines
matchcap int // size of recorded match lengths
prefixComplete bool // prefix is the entire regexp
cond syntax.EmptyOp // empty-width conditions required at start of match
minInputLen int // minimum length of the input in bytes
func ( *Regexp) () {
.longest = true
}
func ( string, syntax.Flags, bool) (*Regexp, error) {
, := syntax.Parse(, )
if != nil {
return nil,
}
:= .MaxCap()
:= .CapNames()
= .Simplify()
, := syntax.Compile()
if != nil {
return nil,
}
:= .NumCap
if < 2 {
= 2
}
:= &Regexp{
expr: ,
prog: ,
onepass: compileOnePass(),
numSubexp: ,
subexpNames: ,
cond: .StartCond(),
longest: ,
matchcap: ,
minInputLen: minInputLen(),
}
if .onepass == nil {
.prefix, .prefixComplete = .Prefix()
.maxBitStateLen = maxBitStateLen()
} else {
.prefix, .prefixComplete, .prefixEnd = onePassPrefix()
}
.prefixBytes = []byte(.prefix)
.prefixRune, _ = utf8.DecodeRuneInString(.prefix)
}
:= len(.Inst)
:= 0
for matchSize[] != 0 && matchSize[] < {
++
}
.mpool =
return , nil
}
func ( *syntax.Regexp) int {
switch .Op {
default:
return 0
case syntax.OpAnyChar, syntax.OpAnyCharNotNL, syntax.OpCharClass:
return 1
case syntax.OpLiteral:
:= 0
for , := range .Rune {
+= utf8.RuneLen()
}
return
case syntax.OpCapture, syntax.OpPlus:
return (.Sub[0])
case syntax.OpRepeat:
return .Min * (.Sub[0])
case syntax.OpConcat:
:= 0
for , := range .Sub {
+= ()
}
return
case syntax.OpAlternate:
:= (.Sub[0])
var int
for , := range .Sub[1:] {
= ()
if < {
=
}
}
return
}
}
func ( *Regexp) () []string {
return .subexpNames
}
type inputString struct {
str string
}
func ( *inputString) ( int) (rune, int) {
if < len(.str) {
:= .str[]
if < utf8.RuneSelf {
return rune(), 1
}
return utf8.DecodeRuneInString(.str[:])
}
return endOfText, 0
}
func ( *inputString) () bool {
return true
}
func ( *inputString) ( *Regexp) bool {
return strings.HasPrefix(.str, .prefix)
}
func ( *inputString) ( *Regexp, int) int {
return strings.Index(.str[:], .prefix)
}
func ( *inputString) ( int) lazyFlag {
type inputBytes struct {
str []byte
}
func ( *inputBytes) ( int) (rune, int) {
if < len(.str) {
:= .str[]
if < utf8.RuneSelf {
return rune(), 1
}
return utf8.DecodeRune(.str[:])
}
return endOfText, 0
}
func ( *inputBytes) () bool {
return true
}
func ( *inputBytes) ( *Regexp) bool {
return bytes.HasPrefix(.str, .prefixBytes)
}
func ( *inputBytes) ( *Regexp, int) int {
return bytes.Index(.str[:], .prefixBytes)
}
func ( *inputBytes) ( int) lazyFlag {
type inputReader struct {
r io.RuneReader
atEOT bool
pos int
}
func ( *inputReader) ( int) (rune, int) {
if !.atEOT && != .pos {
return endOfText, 0
}
, , := .r.ReadRune()
if != nil {
.atEOT = true
return endOfText, 0
}
.pos +=
return ,
}
func ( *inputReader) () bool {
return false
}
func ( *inputReader) ( *Regexp) bool {
return false
}
func ( *inputReader) ( *Regexp, int) int {
return -1
}
func ( *inputReader) ( int) lazyFlag {
return 0 // not used
}
func ( *Regexp) () ( string, bool) {
return .prefix, .prefixComplete
}
func ( string, io.RuneReader) ( bool, error) {
, := Compile()
if != nil {
return false,
}
return .MatchReader(), nil
}
func ( *Regexp) ( string, func(string) string) string {
:= .replaceAll(nil, , 2, func( []byte, []int) []byte {
return append(, ([[0]:[1]])...)
})
return string()
}
func ( *Regexp) ( []byte, string, int, func( []byte, []int) []byte) []byte {
:= 0 // end position of the most recent match
:= 0 // position where we next look for a match
var []byte
var int
if != nil {
= len()
} else {
= len()
}
if > .prog.NumCap {
= .prog.NumCap
}
var [2]int
for <= {
:= .doExecute(nil, , , , , [:0])
if len() == 0 {
break // no more matches
}
if [1] > || [0] == 0 {
= (, )
}
= [1]
var int
if != nil {
_, = utf8.DecodeRune([:])
} else {
_, = utf8.DecodeRuneInString([:])
}
if + > [1] {
+=
++
} else {
= [1]
}
}
var specialBytes [16]byte
func ( byte) bool {
return < utf8.RuneSelf && specialBytes[%16]&(1<<(/16)) != 0
}
func () {
for , := range []byte(`\.+*?()|[]{}^$`) {
specialBytes[%16] |= 1 << ( / 16)
}
}
= false
}
if == nil {
_, = utf8.DecodeRuneInString([:])
} else {
_, = utf8.DecodeRune([:])
}
if > 0 {
+=
} else {
= + 1
}
} else {
= [1]
}
= [1]
if {
(.pad())
++
}
}
}
= append(, '$')
= [1:]
continue
}
=
if >= 0 {
if 2*+1 < len() && [2*] >= 0 {
if != nil {
= append(, [[2*]:[2*+1]]...)
} else {
= append(, [[2*]:[2*+1]]...)
}
}
} else {
for , := range .subexpNames {
if == && 2*+1 < len() && [2*] >= 0 {
if != nil {
= append(, [[2*]:[2*+1]]...)
} else {
= append(, [[2*]:[2*+1]]...)
}
break
}
}
}
}
= append(, ...)
return
}
return
}
= [:]
if {
return
}
++
}
func ( *Regexp) ( string, int) []string {
if == 0 {
return nil
}
if len(.expr) > 0 && len() == 0 {
return []string{""}
}
:= .FindAllStringIndex(, )
:= make([]string, 0, len())
:= 0
:= 0
for , := range {
if > 0 && len() >= -1 {
break
}
= [0]
if [1] != 0 {
= append(, [:])
}
= [1]
}
if != len() {
= append(, [:])
}
return
![]() |
The pages are generated with Golds v0.3.2-preview. (GOOS=darwin GOARCH=amd64) Golds is a Go 101 project developed by Tapir Liu. PR and bug reports are welcome and can be submitted to the issue list. Please follow @Go100and1 (reachable from the left QR code) to get the latest news of Golds. |