"regexp/syntax"
"strings"
"testing"
+ "unicode/utf8"
)
var goodRe = []string{
var metaTests = []MetaTest{
{``, ``, ``, true},
{`foo`, `foo`, `foo`, true},
+ {`日本語+`, `日本語\+`, `日本語`, false},
{`foo\.\$`, `foo\\\.\\\$`, `foo.$`, true}, // has meta but no operator
{`foo.\$`, `foo\.\\\$`, `foo`, false}, // has escaped operators and real operators
{`!@#$%^&*()_+-=[{]}\|,<.>/?~`, `!@#\$%\^&\*\(\)_\+-=\[\{\]\}\\\|,<\.>/\?~`, `!@#`, false},
var sink string
func BenchmarkQuoteMetaAll(b *testing.B) {
- s := string(specialBytes)
+ specials := make([]byte, 0)
+ for i := byte(0); i < utf8.RuneSelf; i++ {
+ if special(i) {
+ specials = append(specials, i)
+ }
+ }
+ s := string(specials)
b.SetBytes(int64(len(s)))
b.ResetTimer()
for i := 0; i < b.N; i++ {
})
}
-var specialBytes = []byte(`\.+*?()|[]{}^$`)
+// Bitmap used by func special to check whether a character needs to be escaped.
+var specialBytes [16]byte
+// special reports whether byte b needs to be escaped by QuoteMeta.
func special(b byte) bool {
- return bytes.IndexByte(specialBytes, b) >= 0
+ return b < utf8.RuneSelf && specialBytes[b%16]&(1<<(b/16)) != 0
+}
+
+func init() {
+ for _, b := range []byte(`\.+*?()|[]{}^$`) {
+ specialBytes[b%16] |= 1 << (b / 16)
+ }
}
// QuoteMeta returns a string that quotes all regular expression metacharacters