diff options
author | Rob Pike <r@golang.org> | 2009-08-05 14:40:34 -0700 |
---|---|---|
committer | Rob Pike <r@golang.org> | 2009-08-05 14:40:34 -0700 |
commit | 79475d55878ee129a94cd669a43c0c0df84969df (patch) | |
tree | fe22e047d9f56c562265aa7c3a539806414386ce /src/pkg/regexp/regexp.go | |
parent | f878417eaeb42a8919a9035eb6cae37b4797e43c (diff) | |
download | golang-79475d55878ee129a94cd669a43c0c0df84969df.tar.gz |
special case: recognize '[^\n]' and make it as fast as '.'
R=rsc
DELTA=25 (23 added, 1 deleted, 1 changed)
OCL=32793
CL=32799
Diffstat (limited to 'src/pkg/regexp/regexp.go')
-rw-r--r-- | src/pkg/regexp/regexp.go | 24 |
1 files changed, 22 insertions, 2 deletions
diff --git a/src/pkg/regexp/regexp.go b/src/pkg/regexp/regexp.go index 1ab9246f6..745a3ae72 100644 --- a/src/pkg/regexp/regexp.go +++ b/src/pkg/regexp/regexp.go @@ -87,7 +87,8 @@ const ( _EOT; // '$' end of text _CHAR; // 'a' regular character _CHARCLASS; // [a-z] character class - _ANY; // '.' any character + _ANY; // '.' any character including newline + _NOTNL; // [^\n] special case: any character but newline _BRA; // '(' parenthesized expression _EBRA; // ')'; end of '(' parenthesized expression _ALT; // '|' alternation @@ -200,6 +201,14 @@ type _Any struct { func (any *_Any) kind() int { return _ANY } func (any *_Any) print() { print("any") } +// --- NOTNL any character but newline +type _NotNl struct { + common +} + +func (notnl *_NotNl) kind() int { return _NOTNL } +func (notnl *_NotNl) print() { print("notnl") } + // --- BRA parenthesized expression type _Bra struct { common; @@ -305,7 +314,6 @@ func specialcclass(c int) bool { func (p *parser) charClass() instr { cc := newCharClass(); - p.re.add(cc); if p.c() == '^' { cc.negate = true; p.nextc(); @@ -317,6 +325,14 @@ func (p *parser) charClass() instr { if left >= 0 { p.re.setError(ErrBadRange); } + // Is it [^\n]? + if cc.negate && cc.ranges.Len() == 2 && + cc.ranges.At(0) == '\n' && cc.ranges.At(1) == '\n' { + nl := new(_NotNl); + p.re.add(nl); + return nl; + } + p.re.add(cc); return cc; case '-': // do this before backslash processing p.re.setError(ErrBadRange); @@ -680,6 +696,10 @@ func (re *Regexp) doExecute(str string, pos int) []int { if c != endOfFile { s[out] = addState(s[out], st.inst.next(), st.match) } + case _NOTNL: + if c != endOfFile && c != '\n' { + s[out] = addState(s[out], st.inst.next(), st.match) + } case _BRA: n := st.inst.(*_Bra).n; st.match[2*n] = pos; |