File: regexp.go

package info (click to toggle)
kitty 0.42.1-1
  • links: PTS, VCS
  • area: main
  • in suites: experimental
  • size: 28,564 kB
  • sloc: ansic: 82,787; python: 55,191; objc: 5,122; sh: 1,295; xml: 364; makefile: 143; javascript: 78
file content (53 lines) | stat: -rw-r--r-- 1,358 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
// License: GPLv3 Copyright: 2022, Kovid Goyal, <kovid at kovidgoyal.net>

package utils

import (
	"fmt"
	"regexp"
	"strings"
)

var _ = fmt.Print

var pat_cache = NewLRUCache[string, *regexp.Regexp](128)

type SubMatch struct {
	Text       string
	Start, End int
}

func Compile(pat string) (*regexp.Regexp, error) {
	return pat_cache.GetOrCreate(pat, regexp.Compile)
}

func MustCompile(pat string) *regexp.Regexp {
	return pat_cache.MustGetOrCreate(pat, regexp.MustCompile)
}

func ReplaceAll(cpat *regexp.Regexp, str string, repl func(full_match string, groupdict map[string]SubMatch) string) string {
	result := strings.Builder{}
	result.Grow(len(str) + 256)
	last_index := 0
	matches := cpat.FindAllStringSubmatchIndex(str, -1)
	names := cpat.SubexpNames()
	groupdict := make(map[string]SubMatch, len(names))
	for _, v := range matches {
		match_start, match_end := v[0], v[1]
		full_match := str[match_start:match_end]
		for k := range groupdict {
			delete(groupdict, k)
		}
		for i, name := range names {
			idx := 2 * i
			if v[idx] > -1 && v[idx+1] > -1 {
				groupdict[name] = SubMatch{Text: str[v[idx]:v[idx+1]], Start: v[idx], End: v[idx+1]}
			}
		}
		result.WriteString(str[last_index:match_start])
		result.WriteString(repl(full_match, groupdict))
		last_index = match_end
	}
	result.WriteString(str[last_index:])
	return result.String()
}