Mercurial > yakumo_izuru > aya
comparison vendor/github.com/dlclark/regexp2/syntax/escape.go @ 66:787b5ee0289d draft
Use vendored modules
Signed-off-by: Izuru Yakumo <yakumo.izuru@chaotic.ninja>
author | yakumo.izuru |
---|---|
date | Sun, 23 Jul 2023 13:18:53 +0000 |
parents | |
children |
comparison
equal
deleted
inserted
replaced
65:6d985efa0f7a | 66:787b5ee0289d |
---|---|
1 package syntax | |
2 | |
3 import ( | |
4 "bytes" | |
5 "strconv" | |
6 "strings" | |
7 "unicode" | |
8 ) | |
9 | |
10 func Escape(input string) string { | |
11 b := &bytes.Buffer{} | |
12 for _, r := range input { | |
13 escape(b, r, false) | |
14 } | |
15 return b.String() | |
16 } | |
17 | |
18 const meta = `\.+*?()|[]{}^$# ` | |
19 | |
20 func escape(b *bytes.Buffer, r rune, force bool) { | |
21 if unicode.IsPrint(r) { | |
22 if strings.IndexRune(meta, r) >= 0 || force { | |
23 b.WriteRune('\\') | |
24 } | |
25 b.WriteRune(r) | |
26 return | |
27 } | |
28 | |
29 switch r { | |
30 case '\a': | |
31 b.WriteString(`\a`) | |
32 case '\f': | |
33 b.WriteString(`\f`) | |
34 case '\n': | |
35 b.WriteString(`\n`) | |
36 case '\r': | |
37 b.WriteString(`\r`) | |
38 case '\t': | |
39 b.WriteString(`\t`) | |
40 case '\v': | |
41 b.WriteString(`\v`) | |
42 default: | |
43 if r < 0x100 { | |
44 b.WriteString(`\x`) | |
45 s := strconv.FormatInt(int64(r), 16) | |
46 if len(s) == 1 { | |
47 b.WriteRune('0') | |
48 } | |
49 b.WriteString(s) | |
50 break | |
51 } | |
52 b.WriteString(`\u`) | |
53 b.WriteString(strconv.FormatInt(int64(r), 16)) | |
54 } | |
55 } | |
56 | |
57 func Unescape(input string) (string, error) { | |
58 idx := strings.IndexRune(input, '\\') | |
59 // no slashes means no unescape needed | |
60 if idx == -1 { | |
61 return input, nil | |
62 } | |
63 | |
64 buf := bytes.NewBufferString(input[:idx]) | |
65 // get the runes for the rest of the string -- we're going full parser scan on this | |
66 | |
67 p := parser{} | |
68 p.setPattern(input[idx+1:]) | |
69 for { | |
70 if p.rightMost() { | |
71 return "", p.getErr(ErrIllegalEndEscape) | |
72 } | |
73 r, err := p.scanCharEscape() | |
74 if err != nil { | |
75 return "", err | |
76 } | |
77 buf.WriteRune(r) | |
78 // are we done? | |
79 if p.rightMost() { | |
80 return buf.String(), nil | |
81 } | |
82 | |
83 r = p.moveRightGetChar() | |
84 for r != '\\' { | |
85 buf.WriteRune(r) | |
86 if p.rightMost() { | |
87 // we're done, no more slashes | |
88 return buf.String(), nil | |
89 } | |
90 // keep scanning until we get another slash | |
91 r = p.moveRightGetChar() | |
92 } | |
93 } | |
94 } |