...

Source file src/github.com/dlclark/regexp2/syntax/escape.go

Documentation: github.com/dlclark/regexp2/syntax

     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  }
    95  

View as plain text