func (re *Regexp) ReplaceAllStringFunc(src string, repl func(string) string) string {
	b := re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte {
		return append(dst, repl(src[match[0]:match[1]])...)
	})
	return string(b)
}
ReplaceAllStringFunc returns a copy of src in which all matches of the
Regexp have been replaced by the return value of function repl applied
to the matched substring. The replacement returned by repl is substituted
directly, without using Expand.
package binaryregexp
import (
	"bytes"
	"io"
	"strconv"
	"strings"
	"sync"
	"unicode"
	"rsc.io/binaryregexp/syntax"
)
type Regexp struct {
	expr           string        
	prog           *syntax.Prog  
	onepass        *onePassProg  
	numSubexp      int
	maxBitStateLen int
	subexpNames    []string
	prefix         string          
	prefixBytes    []byte          
	prefixEnd      uint32          
	mpool          int             
	matchcap       int             
	prefixComplete bool            
	cond           syntax.EmptyOp  
	minInputLen    int             
	longest bool  
}
func (re *Regexp) String() string {
	return re.expr
}
func (re *Regexp) Copy() *Regexp {
	re2 := *re
	return &re2
}
func Compile(expr string) (*Regexp, error) {
	return compile(expr, syntax.Perl, false)
}
func CompilePOSIX(expr string) (*Regexp, error) {
	return compile(expr, syntax.POSIX, true)
}
func (re *Regexp) Longest() {
	re.longest = true
}
func compile(expr string, mode syntax.Flags, longest bool) (*Regexp, error) {
	re, err := syntax.Parse(expr, mode)
	if err != nil {
		return nil, err
	}
	maxCap := re.MaxCap()
	capNames := re.CapNames()
	re = re.Simplify()
	prog, err := syntax.Compile(re)
	if err != nil {
		return nil, err
	}
	matchcap := prog.NumCap
	if matchcap < 2 {
		matchcap = 2
	}
	regexp := &Regexp{
		expr:        expr,
		prog:        prog,
		onepass:     compileOnePass(prog),
		numSubexp:   maxCap,
		subexpNames: capNames,
		cond:        prog.StartCond(),
		longest:     longest,
		matchcap:    matchcap,
		minInputLen: minInputLen(re),
	}
	if regexp.onepass == nil {
		regexp.prefix, regexp.prefixComplete = prog.Prefix()
		regexp.maxBitStateLen = maxBitStateLen(prog)
	} else {
		regexp.prefix, regexp.prefixComplete, regexp.prefixEnd = onePassPrefix(prog)
	}
	if regexp.prefix != "" {
		regexp.prefixBytes = []byte(regexp.prefix)
	}
	n := len(prog.Inst)
	i := 0
	for matchSize[i] != 0 && matchSize[i] < n {
		i++
	}
	regexp.mpool = i
	return regexp, nil
}
var (
	matchSize = [...]int{128, 512, 2048, 16384, 0}
	matchPool [len(matchSize)]sync.Pool
)
func (re *Regexp) get() *machine {
	m, ok := matchPool[re.mpool].Get().(*machine)
	if !ok {
		m = new(machine)
	}
	m.re = re
	m.p = re.prog
	if cap(m.matchcap) < re.matchcap {
		m.matchcap = make([]int, re.matchcap)
		for _, t := range m.pool {
			t.cap = make([]int, re.matchcap)
		}
	}
	n := matchSize[re.mpool]
	if n == 0 {  
		n = len(re.prog.Inst)
	}
	if len(m.q0.sparse) < n {
		m.q0 = queue{make([]uint32, n), make([]entry, 0, n)}
		m.q1 = queue{make([]uint32, n), make([]entry, 0, n)}
	}
	return m
}
func (re *Regexp) put(m *machine) {
	m.re = nil
	m.p = nil
	m.inputs.clear()
	matchPool[re.mpool].Put(m)
}
func minInputLen(re *syntax.Regexp) int {
	switch re.Op {
	default:
		return 0
	case syntax.OpAnyChar, syntax.OpAnyCharNotNL, syntax.OpCharClass:
		return 1
	case syntax.OpLiteral:
		return len(re.Rune)
	case syntax.OpCapture, syntax.OpPlus:
		return minInputLen(re.Sub[0])
	case syntax.OpRepeat:
		return re.Min * minInputLen(re.Sub[0])
	case syntax.OpConcat:
		l := 0
		for _, sub := range re.Sub {
			l += minInputLen(sub)
		}
		return l
	case syntax.OpAlternate:
		l := minInputLen(re.Sub[0])
		var lnext int
		for _, sub := range re.Sub[1:] {
			lnext = minInputLen(sub)
			if lnext < l {
				l = lnext
			}
		}
		return l
	}
}
func MustCompile(str string) *Regexp {
	regexp, err := Compile(str)
	if err != nil {
		panic(`regexp: Compile(` + quote(str) + `): ` + err.Error())
	}
	return regexp
}
func MustCompilePOSIX(str string) *Regexp {
	regexp, err := CompilePOSIX(str)
	if err != nil {
		panic(`regexp: CompilePOSIX(` + quote(str) + `): ` + err.Error())
	}
	return regexp
}
func quote(s string) string {
	if strconv.CanBackquote(s) {
		return "`" + s + "`"
	}
	return strconv.Quote(s)
}
func (re *Regexp) NumSubexp() int {
	return re.numSubexp
}
func (re *Regexp) SubexpNames() []string {
	return re.subexpNames
}
const endOfText rune = -1
type input interface {
	step(pos int) (r rune, width int)  
	canCheckPrefix() bool              
	hasPrefix(re *Regexp) bool
	index(re *Regexp, pos int) int
	context(pos int) lazyFlag
}
type inputString struct {
	str string
}
func (i *inputString) step(pos int) (rune, int) {
	if pos < len(i.str) {
		c := i.str[pos]
		return rune(c), 1
	}
	return endOfText, 0
}
func (i *inputString) canCheckPrefix() bool {
	return true
}
func (i *inputString) hasPrefix(re *Regexp) bool {
	return strings.HasPrefix(i.str, re.prefix)
}
func (i *inputString) index(re *Regexp, pos int) int {
	return strings.Index(i.str[pos:], re.prefix)
}
func (i *inputString) context(pos int) lazyFlag {
	r1, r2 := endOfText, endOfText
	if uint(pos-1) < uint(len(i.str)) {
		r1 = rune(i.str[pos-1])
	}
	if uint(pos) < uint(len(i.str)) {
		r2 = rune(i.str[pos])
	}
	return newLazyFlag(r1, r2)
}
type inputBytes struct {
	str []byte
}
func (i *inputBytes) step(pos int) (rune, int) {
	if pos < len(i.str) {
		c := i.str[pos]
		return rune(c), 1
	}
	return endOfText, 0
}
func (i *inputBytes) canCheckPrefix() bool {
	return true
}
func (i *inputBytes) hasPrefix(re *Regexp) bool {
	return bytes.HasPrefix(i.str, re.prefixBytes)
}
func (i *inputBytes) index(re *Regexp, pos int) int {
	return bytes.Index(i.str[pos:], re.prefixBytes)
}
func (i *inputBytes) context(pos int) lazyFlag {
	r1, r2 := endOfText, endOfText
	if uint(pos-1) < uint(len(i.str)) {
		r1 = rune(i.str[pos-1])
	}
	if uint(pos) < uint(len(i.str)) {
		r2 = rune(i.str[pos])
	}
	return newLazyFlag(r1, r2)
}
type inputReader struct {
	r     io.ByteReader
	atEOT bool
	pos   int
}
func (i *inputReader) step(pos int) (rune, int) {
	if !i.atEOT && pos != i.pos {
		return endOfText, 0
	}
	r, err := i.r.ReadByte()
	if err != nil {
		i.atEOT = true
		return endOfText, 0
	}
	i.pos++
	return rune(r), 1
}
func (i *inputReader) canCheckPrefix() bool {
	return false
}
func (i *inputReader) hasPrefix(re *Regexp) bool {
	return false
}
func (i *inputReader) index(re *Regexp, pos int) int {
	return -1
}
func (i *inputReader) context(pos int) lazyFlag {
	return 0  
}
func (re *Regexp) LiteralPrefix() (prefix string, complete bool) {
	return re.prefix, re.prefixComplete
}
func (re *Regexp) MatchReader(r io.ByteReader) bool {
	return re.doMatch(r, nil, "")
}
func (re *Regexp) MatchString(s string) bool {
	return re.doMatch(nil, nil, s)
}
func (re *Regexp) Match(b []byte) bool {
	return re.doMatch(nil, b, "")
}
func MatchReader(pattern string, r io.ByteReader) (matched bool, err error) {
	re, err := Compile(pattern)
	if err != nil {
		return false, err
	}
	return re.MatchReader(r), nil
}
func MatchString(pattern string, s string) (matched bool, err error) {
	re, err := Compile(pattern)
	if err != nil {
		return false, err
	}
	return re.MatchString(s), nil
}
func Match(pattern string, b []byte) (matched bool, err error) {
	re, err := Compile(pattern)
	if err != nil {
		return false, err
	}
	return re.Match(b), nil
}
func (re *Regexp) ReplaceAllString(src, repl string) string {
	n := 2
	if strings.Contains(repl, "$") {
		n = 2 * (re.numSubexp + 1)
	}
	b := re.replaceAll(nil, src, n, func(dst []byte, match []int) []byte {
		return re.expand(dst, repl, nil, src, match)
	})
	return string(b)
}
func (re *Regexp) ReplaceAllLiteralString(src, repl string) string {
	return string(re.replaceAll(nil, src, 2, func(dst []byte, match []int) []byte {
		return append(dst, repl...)
	}))
}