summaryrefslogtreecommitdiff
path: root/src/pkg/regexp
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2009-12-15 15:40:16 -0800
committerRobert Griesemer <gri@golang.org>2009-12-15 15:40:16 -0800
commit13ac778ef2f757c7cd636b4336a2bd6c8f403b43 (patch)
tree28b6ebc4aa762e38c45f4b0b69d3aee472ed4c3c /src/pkg/regexp
parente4bd81f903362d998f7bfc02095935408aff0bc5 (diff)
downloadgolang-13ac778ef2f757c7cd636b4336a2bd6c8f403b43.tar.gz
1) Change default gofmt default settings for
parsing and printing to new syntax. Use -oldparser to parse the old syntax, use -oldprinter to print the old syntax. 2) Change default gofmt formatting settings to use tabs for indentation only and to use spaces for alignment. This will make the code alignment insensitive to an editor's tabwidth. Use -spaces=false to use tabs for alignment. 3) Manually changed src/exp/parser/parser_test.go so that it doesn't try to parse the parser's source files using the old syntax (they have new syntax now). 4) gofmt -w src misc test/bench 4th set of files. R=rsc CC=golang-dev http://codereview.appspot.com/180049
Diffstat (limited to 'src/pkg/regexp')
-rw-r--r--src/pkg/regexp/all_test.go206
-rw-r--r--src/pkg/regexp/regexp.go892
2 files changed, 549 insertions, 549 deletions
diff --git a/src/pkg/regexp/all_test.go b/src/pkg/regexp/all_test.go
index 6c586ba98..0c274139b 100644
--- a/src/pkg/regexp/all_test.go
+++ b/src/pkg/regexp/all_test.go
@@ -5,9 +5,9 @@
package regexp
import (
- "os";
- "strings";
- "testing";
+ "os"
+ "strings"
+ "testing"
)
var good_re = []string{
@@ -32,8 +32,8 @@ var good_re = []string{
// TODO: nice to do this with a map
type stringError struct {
- re string;
- err os.Error;
+ re string
+ err os.Error
}
var bad_re = []stringError{
@@ -54,9 +54,9 @@ var bad_re = []stringError{
type vec []int
type tester struct {
- re string;
- text string;
- match vec;
+ re string
+ text string
+ match vec
}
var matches = []tester{
@@ -100,27 +100,27 @@ var matches = []tester{
}
func compileTest(t *testing.T, expr string, error os.Error) *Regexp {
- re, err := Compile(expr);
+ re, err := Compile(expr)
if err != error {
t.Error("compiling `", expr, "`; unexpected error: ", err.String())
}
- return re;
+ return re
}
func printVec(t *testing.T, m []int) {
- l := len(m);
+ l := len(m)
if l == 0 {
t.Log("\t<no match>")
} else {
if m[len(m)-1] == -1 {
m = m[0 : len(m)-2]
}
- t.Log("\t", m);
+ t.Log("\t", m)
}
}
func equal(m1, m2 []int) bool {
- l := len(m1);
+ l := len(m1)
if l != len(m2) {
return false
}
@@ -129,11 +129,11 @@ func equal(m1, m2 []int) bool {
return false
}
}
- return true;
+ return true
}
func equalStrings(m1, m2 []string) bool {
- l := len(m1);
+ l := len(m1)
if l != len(m2) {
return false
}
@@ -142,28 +142,28 @@ func equalStrings(m1, m2 []string) bool {
return false
}
}
- return true;
+ return true
}
func executeTest(t *testing.T, expr string, str string, match []int) {
- re := compileTest(t, expr, nil);
+ re := compileTest(t, expr, nil)
if re == nil {
return
}
- m := re.ExecuteString(str);
+ m := re.ExecuteString(str)
if !equal(m, match) {
- t.Errorf("ExecuteString failure on %#q matching %q:", expr, str);
- printVec(t, m);
- t.Log("should be:");
- printVec(t, match);
+ t.Errorf("ExecuteString failure on %#q matching %q:", expr, str)
+ printVec(t, m)
+ t.Log("should be:")
+ printVec(t, match)
}
// now try bytes
- m = re.Execute(strings.Bytes(str));
+ m = re.Execute(strings.Bytes(str))
if !equal(m, match) {
- t.Errorf("Execute failure on %#q matching %q:", expr, str);
- printVec(t, m);
- t.Log("should be:");
- printVec(t, match);
+ t.Errorf("Execute failure on %#q matching %q:", expr, str)
+ printVec(t, m)
+ t.Log("should be:")
+ printVec(t, match)
}
}
@@ -181,22 +181,22 @@ func TestBadCompile(t *testing.T) {
func TestExecute(t *testing.T) {
for i := 0; i < len(matches); i++ {
- test := &matches[i];
- executeTest(t, test.re, test.text, test.match);
+ test := &matches[i]
+ executeTest(t, test.re, test.text, test.match)
}
}
func matchTest(t *testing.T, expr string, str string, match []int) {
- re := compileTest(t, expr, nil);
+ re := compileTest(t, expr, nil)
if re == nil {
return
}
- m := re.MatchString(str);
+ m := re.MatchString(str)
if m != (len(match) > 0) {
t.Errorf("MatchString failure on %#q matching %q: %t should be %t", expr, str, m, len(match) > 0)
}
// now try bytes
- m = re.Match(strings.Bytes(str));
+ m = re.Match(strings.Bytes(str))
if m != (len(match) > 0) {
t.Errorf("Match failure on %#q matching %q: %t should be %t", expr, str, m, len(match) > 0)
}
@@ -204,20 +204,20 @@ func matchTest(t *testing.T, expr string, str string, match []int) {
func TestMatch(t *testing.T) {
for i := 0; i < len(matches); i++ {
- test := &matches[i];
- matchTest(t, test.re, test.text, test.match);
+ test := &matches[i]
+ matchTest(t, test.re, test.text, test.match)
}
}
func TestMatchStrings(t *testing.T) {
for i := 0; i < len(matches); i++ {
- test := &matches[i];
- matchTest(t, test.re, test.text, test.match);
+ test := &matches[i]
+ matchTest(t, test.re, test.text, test.match)
}
}
func matchFunctionTest(t *testing.T, expr string, str string, match []int) {
- m, err := MatchString(expr, str);
+ m, err := MatchString(expr, str)
if err == nil {
return
}
@@ -228,13 +228,13 @@ func matchFunctionTest(t *testing.T, expr string, str string, match []int) {
func TestMatchFunction(t *testing.T) {
for i := 0; i < len(matches); i++ {
- test := &matches[i];
- matchFunctionTest(t, test.re, test.text, test.match);
+ test := &matches[i]
+ matchFunctionTest(t, test.re, test.text, test.match)
}
}
type ReplaceTest struct {
- pattern, replacement, input, output string;
+ pattern, replacement, input, output string
}
var replaceTests = []ReplaceTest{
@@ -301,18 +301,18 @@ var replaceTests = []ReplaceTest{
func TestReplaceAll(t *testing.T) {
for _, tc := range replaceTests {
- re, err := Compile(tc.pattern);
+ re, err := Compile(tc.pattern)
if err != nil {
- t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err);
- continue;
+ t.Errorf("Unexpected error compiling %q: %v", tc.pattern, err)
+ continue
}
- actual := re.ReplaceAllString(tc.input, tc.replacement);
+ actual := re.ReplaceAllString(tc.input, tc.replacement)
if actual != tc.output {
t.Errorf("%q.Replace(%q,%q) = %q; want %q",
tc.pattern, tc.input, tc.replacement, actual, tc.output)
}
// now try bytes
- actual = string(re.ReplaceAll(strings.Bytes(tc.input), strings.Bytes(tc.replacement)));
+ actual = string(re.ReplaceAll(strings.Bytes(tc.input), strings.Bytes(tc.replacement)))
if actual != tc.output {
t.Errorf("%q.Replace(%q,%q) = %q; want %q",
tc.pattern, tc.input, tc.replacement, actual, tc.output)
@@ -321,7 +321,7 @@ func TestReplaceAll(t *testing.T) {
}
type QuoteMetaTest struct {
- pattern, output string;
+ pattern, output string
}
var quoteMetaTests = []QuoteMetaTest{
@@ -333,25 +333,25 @@ var quoteMetaTests = []QuoteMetaTest{
func TestQuoteMeta(t *testing.T) {
for _, tc := range quoteMetaTests {
// Verify that QuoteMeta returns the expected string.
- quoted := QuoteMeta(tc.pattern);
+ quoted := QuoteMeta(tc.pattern)
if quoted != tc.output {
t.Errorf("QuoteMeta(`%s`) = `%s`; want `%s`",
- tc.pattern, quoted, tc.output);
- continue;
+ tc.pattern, quoted, tc.output)
+ continue
}
// Verify that the quoted string is in fact treated as expected
// by Compile -- i.e. that it matches the original, unquoted string.
if tc.pattern != "" {
- re, err := Compile(quoted);
+ re, err := Compile(quoted)
if err != nil {
- t.Errorf("Unexpected error compiling QuoteMeta(`%s`): %v", tc.pattern, err);
- continue;
+ t.Errorf("Unexpected error compiling QuoteMeta(`%s`): %v", tc.pattern, err)
+ continue
}
- src := "abc" + tc.pattern + "def";
- repl := "xyz";
- replaced := re.ReplaceAllString(src, repl);
- expected := "abcxyzdef";
+ src := "abc" + tc.pattern + "def"
+ repl := "xyz"
+ replaced := re.ReplaceAllString(src, repl)
+ expected := "abcxyzdef"
if replaced != expected {
t.Errorf("QuoteMeta(`%s`).Replace(`%s`,`%s`) = `%s`; want `%s`",
tc.pattern, src, repl, replaced, expected)
@@ -361,11 +361,11 @@ func TestQuoteMeta(t *testing.T) {
}
type matchCase struct {
- matchfunc string;
- input string;
- n int;
- regexp string;
- expected []string;
+ matchfunc string
+ input string
+ n int
+ regexp string
+ expected []string
}
var matchCases = []matchCase{
@@ -392,90 +392,90 @@ func printStringSlice(t *testing.T, s []string) {
}
func TestAllMatches(t *testing.T) {
- ch := make(chan matchCase);
+ ch := make(chan matchCase)
go func() {
for _, c := range matchCases {
- ch <- c;
+ ch <- c
stringCase := matchCase{
"string" + c.matchfunc,
c.input,
c.n,
c.regexp,
c.expected,
- };
- ch <- stringCase;
+ }
+ ch <- stringCase
}
- close(ch);
- }();
+ close(ch)
+ }()
for c := range ch {
- var result []string;
- re, _ := Compile(c.regexp);
+ var result []string
+ re, _ := Compile(c.regexp)
switch c.matchfunc {
case "matchit":
- result = make([]string, len(c.input)+1);
- i := 0;
- b := strings.Bytes(c.input);
+ result = make([]string, len(c.input)+1)
+ i := 0
+ b := strings.Bytes(c.input)
for match := range re.AllMatchesIter(b, c.n) {
- result[i] = string(match);
- i++;
+ result[i] = string(match)
+ i++
}
- result = result[0:i];
+ result = result[0:i]
case "stringmatchit":
- result = make([]string, len(c.input)+1);
- i := 0;
+ result = make([]string, len(c.input)+1)
+ i := 0
for match := range re.AllMatchesStringIter(c.input, c.n) {
- result[i] = match;
- i++;
+ result[i] = match
+ i++
}
- result = result[0:i];
+ result = result[0:i]
case "match":
- result = make([]string, len(c.input)+1);
- b := strings.Bytes(c.input);
- i := 0;
+ result = make([]string, len(c.input)+1)
+ b := strings.Bytes(c.input)
+ i := 0
for _, match := range re.AllMatches(b, c.n) {
- result[i] = string(match);
- i++;
+ result[i] = string(match)
+ i++
}
- result = result[0:i];
+ result = result[0:i]
case "stringmatch":
result = re.AllMatchesString(c.input, c.n)
}
if !equalStrings(result, c.expected) {
t.Errorf("testing '%s'.%s('%s', %d), expected: ",
- c.regexp, c.matchfunc, c.input, c.n);
- printStringSlice(t, c.expected);
- t.Log("got: ");
- printStringSlice(t, result);
- t.Log("\n");
+ c.regexp, c.matchfunc, c.input, c.n)
+ printStringSlice(t, c.expected)
+ t.Log("got: ")
+ printStringSlice(t, result)
+ t.Log("\n")
}
}
}
func BenchmarkLiteral(b *testing.B) {
- x := strings.Repeat("x", 50);
- b.StopTimer();
- re, _ := Compile(x);
- b.StartTimer();
+ x := strings.Repeat("x", 50)
+ b.StopTimer()
+ re, _ := Compile(x)
+ b.StartTimer()
for i := 0; i < b.N; i++ {
if !re.MatchString(x) {
- println("no match!");
- break;
+ println("no match!")
+ break
}
}
}
func BenchmarkNotLiteral(b *testing.B) {
- x := strings.Repeat("x", 49);
- b.StopTimer();
- re, _ := Compile("^" + x);
- b.StartTimer();
+ x := strings.Repeat("x", 49)
+ b.StopTimer()
+ re, _ := Compile("^" + x)
+ b.StartTimer()
for i := 0; i < b.N; i++ {
if !re.MatchString(x) {
- println("no match!");
- break;
+ println("no match!")
+ break
}
}
}
diff --git a/src/pkg/regexp/regexp.go b/src/pkg/regexp/regexp.go
index 6135fb61b..fd6fbefee 100644
--- a/src/pkg/regexp/regexp.go
+++ b/src/pkg/regexp/regexp.go
@@ -23,144 +23,144 @@
package regexp
import (
- "bytes";
- "container/vector";
- "io";
- "os";
- "strings";
- "utf8";
+ "bytes"
+ "container/vector"
+ "io"
+ "os"
+ "strings"
+ "utf8"
)
var debug = false
// Error codes returned by failures to parse an expression.
var (
- ErrInternal = os.NewError("internal error");
- ErrUnmatchedLpar = os.NewError("unmatched '('");
- ErrUnmatchedRpar = os.NewError("unmatched ')'");
- ErrUnmatchedLbkt = os.NewError("unmatched '['");
- ErrUnmatchedRbkt = os.NewError("unmatched ']'");
- ErrBadRange = os.NewError("bad range in character class");
- ErrExtraneousBackslash = os.NewError("extraneous backslash");
- ErrBadClosure = os.NewError("repeated closure (**, ++, etc.)");
- ErrBareClosure = os.NewError("closure applies to nothing");
- ErrBadBackslash = os.NewError("illegal backslash escape");
+ ErrInternal = os.NewError("internal error")
+ ErrUnmatchedLpar = os.NewError("unmatched '('")
+ ErrUnmatchedRpar = os.NewError("unmatched ')'")
+ ErrUnmatchedLbkt = os.NewError("unmatched '['")
+ ErrUnmatchedRbkt = os.NewError("unmatched ']'")
+ ErrBadRange = os.NewError("bad range in character class")
+ ErrExtraneousBackslash = os.NewError("extraneous backslash")
+ ErrBadClosure = os.NewError("repeated closure (**, ++, etc.)")
+ ErrBareClosure = os.NewError("closure applies to nothing")
+ ErrBadBackslash = os.NewError("illegal backslash escape")
)
// An instruction executed by the NFA
type instr interface {
- kind() int; // the type of this instruction: _CHAR, _ANY, etc.
- next() instr; // the instruction to execute after this one
- setNext(i instr);
- index() int;
- setIndex(i int);
- print();
+ kind() int // the type of this instruction: _CHAR, _ANY, etc.
+ next() instr // the instruction to execute after this one
+ setNext(i instr)
+ index() int
+ setIndex(i int)
+ print()
}
// Fields and methods common to all instructions
type common struct {
- _next instr;
- _index int;
+ _next instr
+ _index int
}
-func (c *common) next() instr { return c._next }
-func (c *common) setNext(i instr) { c._next = i }
-func (c *common) index() int { return c._index }
-func (c *common) setIndex(i int) { c._index = i }
+func (c *common) next() instr { return c._next }
+func (c *common) setNext(i instr) { c._next = i }
+func (c *common) index() int { return c._index }
+func (c *common) setIndex(i int) { c._index = i }
// Regexp is the representation of a compiled regular expression.
// The public interface is entirely through methods.
type Regexp struct {
- expr string; // the original expression
- prefix string; // initial plain text string
- prefixBytes []byte; // initial plain text bytes
- inst *vector.Vector;
- start instr;
- nbra int; // number of brackets in expression, for subexpressions
+ expr string // the original expression
+ prefix string // initial plain text string
+ prefixBytes []byte // initial plain text bytes
+ inst *vector.Vector
+ start instr
+ nbra int // number of brackets in expression, for subexpressions
}
const (
- _START = iota; // beginning of program
- _END; // end of program: success
- _BOT; // '^' beginning of text
- _EOT; // '$' end of text
- _CHAR; // 'a' regular character
- _CHARCLASS; // [a-z] character class
- _ANY; // '.' any character including newline
- _NOTNL; // [^\n] special case: any character but newline
- _BRA; // '(' parenthesized expression
- _EBRA; // ')'; end of '(' parenthesized expression
- _ALT; // '|' alternation
- _NOP; // do nothing; makes it easy to link without patching
+ _START = iota // beginning of program
+ _END // end of program: success
+ _BOT // '^' beginning of text
+ _EOT // '$' end of text
+ _CHAR // 'a' regular character
+ _CHARCLASS // [a-z] character class
+ _ANY // '.' any character including newline
+ _NOTNL // [^\n] special case: any character but newline
+ _BRA // '(' parenthesized expression
+ _EBRA // ')'; end of '(' parenthesized expression
+ _ALT // '|' alternation
+ _NOP // do nothing; makes it easy to link without patching
)
// --- START start of program
type _Start struct {
- common;
+ common
}
-func (start *_Start) kind() int { return _START }
-func (start *_Start) print() { print("start") }
+func (start *_Start) kind() int { return _START }
+func (start *_Start) print() { print("start") }
// --- END end of program
type _End struct {
- common;
+ common
}
-func (end *_End) kind() int { return _END }
-func (end *_End) print() { print("end") }
+func (end *_End) kind() int { return _END }
+func (end *_End) print() { print("end") }
// --- BOT beginning of text
type _Bot struct {
- common;
+ common
}
-func (bot *_Bot) kind() int { return _BOT }
-func (bot *_Bot) print() { print("bot") }
+func (bot *_Bot) kind() int { return _BOT }
+func (bot *_Bot) print() { print("bot") }
// --- EOT end of text
type _Eot struct {
- common;
+ common
}
-func (eot *_Eot) kind() int { return _EOT }
-func (eot *_Eot) print() { print("eot") }
+func (eot *_Eot) kind() int { return _EOT }
+func (eot *_Eot) print() { print("eot") }
// --- CHAR a regular character
type _Char struct {
- common;
- char int;
+ common
+ char int
}
-func (char *_Char) kind() int { return _CHAR }
-func (char *_Char) print() { print("char ", string(char.char)) }
+func (char *_Char) kind() int { return _CHAR }
+func (char *_Char) print() { print("char ", string(char.char)) }
func newChar(char int) *_Char {
- c := new(_Char);
- c.char = char;
- return c;
+ c := new(_Char)
+ c.char = char
+ return c
}
// --- CHARCLASS [a-z]
type _CharClass struct {
- common;
- char int;
- negate bool; // is character class negated? ([^a-z])
+ common
+ char int
+ negate bool // is character class negated? ([^a-z])
// vector of int, stored pairwise: [a-z] is (a,z); x is (x,x):
- ranges *vector.IntVector;
+ ranges *vector.IntVector
}
-func (cclass *_CharClass) kind() int { return _CHARCLASS }
+func (cclass *_CharClass) kind() int { return _CHARCLASS }
func (cclass *_CharClass) print() {
- print("charclass");
+ print("charclass")
if cclass.negate {
print(" (negated)")
}
for i := 0; i < cclass.ranges.Len(); i += 2 {
- l := cclass.ranges.At(i);
- r := cclass.ranges.At(i + 1);
+ l := cclass.ranges.At(i)
+ r := cclass.ranges.At(i + 1)
if l == r {
print(" [", string(l), "]")
} else {
@@ -171,112 +171,112 @@ func (cclass *_CharClass) print() {
func (cclass *_CharClass) addRange(a, b int) {
// range is a through b inclusive
- cclass.ranges.Push(a);
- cclass.ranges.Push(b);
+ cclass.ranges.Push(a)
+ cclass.ranges.Push(b)
}
func (cclass *_CharClass) matches(c int) bool {
for i := 0; i < cclass.ranges.Len(); i = i + 2 {
- min := cclass.ranges.At(i);
- max := cclass.ranges.At(i + 1);
+ min := cclass.ranges.At(i)
+ max := cclass.ranges.At(i + 1)
if min <= c && c <= max {
return !cclass.negate
}
}
- return cclass.negate;
+ return cclass.negate
}
func newCharClass() *_CharClass {
- c := new(_CharClass);
- c.ranges = new(vector.IntVector);
- return c;
+ c := new(_CharClass)
+ c.ranges = new(vector.IntVector)
+ return c
}
// --- ANY any character
type _Any struct {
- common;
+ common
}
-func (any *_Any) kind() int { return _ANY }
-func (any *_Any) print() { print("any") }
+func (any *_Any) kind() int { return _ANY }
+func (any *_Any) print() { print("any") }
// --- NOTNL any character but newline
type _NotNl struct {
- common;
+ common
}
-func (notnl *_NotNl) kind() int { return _NOTNL }
-func (notnl *_NotNl) print() { print("notnl") }
+func (notnl *_NotNl) kind() int { return _NOTNL }
+func (notnl *_NotNl) print() { print("notnl") }
// --- BRA parenthesized expression
type _Bra struct {
- common;
- n int; // subexpression number
+ common
+ n int // subexpression number
}
-func (bra *_Bra) kind() int { return _BRA }
-func (bra *_Bra) print() { print("bra", bra.n) }
+func (bra *_Bra) kind() int { return _BRA }
+func (bra *_Bra) print() { print("bra", bra.n) }
// --- EBRA end of parenthesized expression
type _Ebra struct {
- common;
- n int; // subexpression number
+ common
+ n int // subexpression number
}
-func (ebra *_Ebra) kind() int { return _EBRA }
-func (ebra *_Ebra) print() { print("ebra ", ebra.n) }
+func (ebra *_Ebra) kind() int { return _EBRA }
+func (ebra *_Ebra) print() { print("ebra ", ebra.n) }
// --- ALT alternation
type _Alt struct {
- common;
- left instr; // other branch
+ common
+ left instr // other branch
}
-func (alt *_Alt) kind() int { return _ALT }
-func (alt *_Alt) print() { print("alt(", alt.left.index(), ")") }
+func (alt *_Alt) kind() int { return _ALT }
+func (alt *_Alt) print() { print("alt(", alt.left.index(), ")") }
// --- NOP no operation
type _Nop struct {
- common;
+ common
}
-func (nop *_Nop) kind() int { return _NOP }
-func (nop *_Nop) print() { print("nop") }
+func (nop *_Nop) kind() int { return _NOP }
+func (nop *_Nop) print() { print("nop") }
func (re *Regexp) add(i instr) instr {
- i.setIndex(re.inst.Len());
- re.inst.Push(i);
- return i;
+ i.setIndex(re.inst.Len())
+ re.inst.Push(i)
+ return i
}
type parser struct {
- re *Regexp;
- error os.Error;
- nlpar int; // number of unclosed lpars
- pos int;
- ch int;
+ re *Regexp
+ error os.Error
+ nlpar int // number of unclosed lpars
+ pos int
+ ch int
}
const endOfFile = -1
-func (p *parser) c() int { return p.ch }
+func (p *parser) c() int { return p.ch }
func (p *parser) nextc() int {
if p.pos >= len(p.re.expr) {
p.ch = endOfFile
} else {
- c, w := utf8.DecodeRuneInString(p.re.expr[p.pos:]);
- p.ch = c;
- p.pos += w;
+ c, w := utf8.DecodeRuneInString(p.re.expr[p.pos:])
+ p.ch = c
+ p.pos += w
}
- return p.ch;
+ return p.ch
}
func newParser(re *Regexp) *parser {
- p := new(parser);
- p.re = re;
- p.nextc(); // load p.ch
- return p;
+ p := new(parser)
+ p.re = re
+ p.nextc() // load p.ch
+ return p
}
func special(c int) bool {
@@ -285,7 +285,7 @@ func special(c int) bool {
return true
}
}
- return false;
+ return false
}
func specialcclass(c int) bool {
@@ -294,76 +294,76 @@ func specialcclass(c int) bool {
return true
}
}
- return false;
+ return false
}
func (p *parser) charClass() instr {
- cc := newCharClass();
+ cc := newCharClass()
if p.c() == '^' {
- cc.negate = true;
- p.nextc();
+ cc.negate = true
+ p.nextc()
}
- left := -1;
+ left := -1
for {
switch c := p.c(); c {
case ']', endOfFile:
if left >= 0 {
- p.error = ErrBadRange;
- return nil;
+ p.error = ErrBadRange
+ return nil
}
// 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;
+ nl := new(_NotNl)
+ p.re.add(nl)
+ return nl
}
// Special common case: "[a]" -> "a"
if !cc.negate && cc.ranges.Len() == 2 && cc.ranges.At(0) == cc.ranges.At(1) {
- c := newChar(cc.ranges.At(0));
- p.re.add(c);
- return c;
+ c := newChar(cc.ranges.At(0))
+ p.re.add(c)
+ return c
}
- p.re.add(cc);
- return cc;
- case '-': // do this before backslash processing
- p.error = ErrBadRange;
- return nil;
+ p.re.add(cc)
+ return cc
+ case '-': // do this before backslash processing
+ p.error = ErrBadRange
+ return nil
case '\\':
- c = p.nextc();
+ c = p.nextc()
switch {
case c == endOfFile:
- p.error = ErrExtraneousBackslash;
- return nil;
+ p.error = ErrExtraneousBackslash
+ return nil
case c == 'n':
c = '\n'
case specialcclass(c):
// c is as delivered
default:
- p.error = ErrBadBackslash;
- return nil;
+ p.error = ErrBadBackslash
+ return nil
}
- fallthrough;
+ fallthrough
default:
- p.nextc();
+ p.nextc()
switch {
- case left < 0: // first of pair
- if p.c() == '-' { // range
- p.nextc();
- left = c;
- } else { // single char
+ case left < 0: // first of pair
+ if p.c() == '-' { // range
+ p.nextc()
+ left = c
+ } else { // single char
cc.addRange(c, c)
}
- case left <= c: // second of pair
- cc.addRange(left, c);
- left = -1;
+ case left <= c: // second of pair
+ cc.addRange(left, c)
+ left = -1
default:
- p.error = ErrBadRange;
- return nil;
+ p.error = ErrBadRange
+ return nil
}
}
}
- return nil;
+ return nil
}
func (p *parser) term() (start, end instr) {
@@ -378,126 +378,126 @@ func (p *parser) term() (start, end instr) {
case '|', endOfFile:
return nil, nil
case '*', '+':
- p.error = ErrBareClosure;
- return;
+ p.error = ErrBareClosure
+ return
case ')':
if p.nlpar == 0 {
- p.error = ErrUnmatchedRpar;
- return;
+ p.error = ErrUnmatchedRpar
+ return
}
- return nil, nil;
+ return nil, nil
case ']':
- p.error = ErrUnmatchedRbkt;
- return;
+ p.error = ErrUnmatchedRbkt
+ return
case '^':
- p.nextc();
- start = p.re.add(new(_Bot));
- return start, start;
+ p.nextc()
+ start = p.re.add(new(_Bot))
+ return start, start
case '$':
- p.nextc();
- start = p.re.add(new(_Eot));
- return start, start;
+ p.nextc()
+ start = p.re.add(new(_Eot))
+ return start, start
case '.':
- p.nextc();
- start = p.re.add(new(_Any));
- return start, start;
+ p.nextc()
+ start = p.re.add(new(_Any))
+ return start, start
case '[':
- p.nextc();
- start = p.charClass();
+ p.nextc()
+ start = p.charClass()
if p.error != nil {
return
}
if p.c() != ']' {
- p.error = ErrUnmatchedLbkt;
- return;
+ p.error = ErrUnmatchedLbkt
+ return
}
- p.nextc();
- return start, start;
+ p.nextc()
+ return start, start
case '(':
- p.nextc();
- p.nlpar++;
- p.re.nbra++; // increment first so first subexpr is \1
- nbra := p.re.nbra;
- start, end = p.regexp();
+ p.nextc()
+ p.nlpar++
+ p.re.nbra++ // increment first so first subexpr is \1
+ nbra := p.re.nbra
+ start, end = p.regexp()
if p.c() != ')' {
- p.error = ErrUnmatchedLpar;
- return;
+ p.error = ErrUnmatchedLpar
+ return
}
- p.nlpar--;
- p.nextc();
- bra := new(_Bra);
- p.re.add(bra);
- ebra := new(_Ebra);
- p.re.add(ebra);
- bra.n = nbra;
- ebra.n = nbra;
+ p.nlpar--
+ p.nextc()
+ bra := new(_Bra)
+ p.re.add(bra)
+ ebra := new(_Ebra)
+ p.re.add(ebra)
+ bra.n = nbra
+ ebra.n = nbra
if start == nil {
if end == nil {
- p.error = ErrInternal;
- return;
+ p.error = ErrInternal
+ return
}
- start = ebra;
+ start = ebra
} else {
end.setNext(ebra)
}
- bra.setNext(start);
- return bra, ebra;
+ bra.setNext(start)
+ return bra, ebra
case '\\':
- c = p.nextc();
+ c = p.nextc()
switch {
case c == endOfFile:
- p.error = ErrExtraneousBackslash;
- return;
+ p.error = ErrExtraneousBackslash
+ return
case c == 'n':
c = '\n'
case special(c):
// c is as delivered
default:
- p.error = ErrBadBackslash;
- return;
+ p.error = ErrBadBackslash
+ return
}
- fallthrough;
+ fallthrough
default:
- p.nextc();
- start = newChar(c);
- p.re.add(start);
- return start, start;
+ p.nextc()
+ start = newChar(c)
+ p.re.add(start)
+ return start, start
}
- panic("unreachable");
+ panic("unreachable")
}
func (p *parser) closure() (start, end instr) {
- start, end = p.term();
+ start, end = p.term()
if start == nil || p.error != nil {
return
}
switch p.c() {
case '*':
// (start,end)*:
- alt := new(_Alt);
- p.re.add(alt);
- end.setNext(alt); // after end, do alt
- alt.left = start; // alternate brach: return to start
- start = alt; // alt becomes new (start, end)
- end = alt;
+ alt := new(_Alt)
+ p.re.add(alt)
+ end.setNext(alt) // after end, do alt
+ alt.left = start // alternate brach: return to start
+ start = alt // alt becomes new (start, end)
+ end = alt
case '+':
// (start,end)+:
- alt := new(_Alt);
- p.re.add(alt);
- end.setNext(alt); // after end, do alt
- alt.left = start; // alternate brach: return to start
- end = alt; // start is unchanged; end is alt
+ alt := new(_Alt)
+ p.re.add(alt)
+ end.setNext(alt) // after end, do alt
+ alt.left = start // alternate brach: return to start
+ end = alt // start is unchanged; end is alt
case '?':
// (start,end)?:
- alt := new(_Alt);
- p.re.add(alt);
- nop := new(_Nop);
- p.re.add(nop);
- alt.left = start; // alternate branch is start
- alt.setNext(nop); // follow on to nop
- end.setNext(nop); // after end, go to nop
- start = alt; // start is now alt
- end = nop; // end is nop pointed to by both branches
+ alt := new(_Alt)
+ p.re.add(alt)
+ nop := new(_Nop)
+ p.re.add(nop)
+ alt.left = start // alternate branch is start
+ alt.setNext(nop) // follow on to nop
+ end.setNext(nop) // after end, go to nop
+ start = alt // start is now alt
+ end = nop // end is nop pointed to by both branches
default:
return
}
@@ -505,34 +505,34 @@ func (p *parser) closure() (start, end instr) {
case '*', '+', '?':
p.error = ErrBadClosure
}
- return;
+ return
}
func (p *parser) concatenation() (start, end instr) {
for {
- nstart, nend := p.closure();
+ nstart, nend := p.closure()
if p.error != nil {
return
}
switch {
- case nstart == nil: // end of this concatenation
- if start == nil { // this is the empty string
- nop := p.re.add(new(_Nop));
- return nop, nop;
+ case nstart == nil: // end of this concatenation
+ if start == nil { // this is the empty string
+ nop := p.re.add(new(_Nop))
+ return nop, nop
}
- return;
- case start == nil: // this is first element of concatenation
+ return
+ case start == nil: // this is first element of concatenation
start, end = nstart, nend
default:
- end.setNext(nstart);
- end = nend;
+ end.setNext(nstart)
+ end = nend
}
}
- panic("unreachable");
+ panic("unreachable")
}
func (p *parser) regexp() (start, end instr) {
- start, end = p.concatenation();
+ start, end = p.concatenation()
if p.error != nil {
return
}
@@ -541,101 +541,101 @@ func (p *parser) regexp() (start, end instr) {
default:
return
case '|':
- p.nextc();
- nstart, nend := p.concatenation();
+ p.nextc()
+ nstart, nend := p.concatenation()
if p.error != nil {
return
}
- alt := new(_Alt);
- p.re.add(alt);
- alt.left = start;
- alt.setNext(nstart);
- nop := new(_Nop);
- p.re.add(nop);
- end.setNext(nop);
- nend.setNext(nop);
- start, end = alt, nop;
+ alt := new(_Alt)
+ p.re.add(alt)
+ alt.left = start
+ alt.setNext(nstart)
+ nop := new(_Nop)
+ p.re.add(nop)
+ end.setNext(nop)
+ nend.setNext(nop)
+ start, end = alt, nop
}
}
- panic("unreachable");
+ panic("unreachable")
}
func unNop(i instr) instr {
for i.kind() == _NOP {
i = i.next()
}
- return i;
+ return i
}
func (re *Regexp) eliminateNops() {
for i := 0; i < re.inst.Len(); i++ {
- inst := re.inst.At(i).(instr);
+ inst := re.inst.At(i).(instr)
if inst.kind() == _END {
continue
}
- inst.setNext(unNop(inst.next()));
+ inst.setNext(unNop(inst.next()))
if inst.kind() == _ALT {
- alt := inst.(*_Alt);
- alt.left = unNop(alt.left);
+ alt := inst.(*_Alt)
+ alt.left = unNop(alt.left)
}
}
}
func (re *Regexp) dump() {
- print("prefix <", re.prefix, ">\n");
+ print("prefix <", re.prefix, ">\n")
for i := 0; i < re.inst.Len(); i++ {
- inst := re.inst.At(i).(instr);
- print(inst.index(), ": ");
- inst.print();
+ inst := re.inst.At(i).(instr)
+ print(inst.index(), ": ")
+ inst.print()
if inst.kind() != _END {
print(" -> ", inst.next().index())
}
- print("\n");
+ print("\n")
}
}
func (re *Regexp) doParse() os.Error {
- p := newParser(re);
- start := new(_Start);
- re.add(start);
- s, e := p.regexp();
+ p := newParser(re)
+ start := new(_Start)
+ re.add(start)
+ s, e := p.regexp()
if p.error != nil {
return p.error
}
- start.setNext(s);
- re.start = start;
- e.setNext(re.add(new(_End)));
+ start.setNext(s)
+ re.start = start
+ e.setNext(re.add(new(_End)))
if debug {
- re.dump();
- println();
+ re.dump()
+ println()
}
- re.eliminateNops();
+ re.eliminateNops()
if debug {
- re.dump();
- println();
+ re.dump()
+ println()
}
if p.error == nil {
- re.setPrefix();
+ re.setPrefix()
if debug {
- re.dump();
- println();
+ re.dump()
+ println()
}
}
- return p.error;
+ return p.error
}
// Extract regular text from the beginning of the pattern.
// That text can be used by doExecute to speed up matching.
func (re *Regexp) setPrefix() {
- var b []byte;
- var utf = make([]byte, utf8.UTFMax);
+ var b []byte
+ var utf = make([]byte, utf8.UTFMax)
// First instruction is start; skip that.
- i := re.inst.At(0).(instr).next().index();
+ i := re.inst.At(0).(instr).next().index()
Loop:
for i < re.inst.Len() {
- inst := re.inst.At(i).(instr);
+ inst := re.inst.At(i).(instr)
// stop if this is not a char
if inst.kind() != _CHAR {
break
@@ -646,96 +646,96 @@ Loop:
case _BOT, _EOT, _ALT:
break Loop
}
- n := utf8.EncodeRune(inst.(*_Char).char, utf);
- b = bytes.Add(b, utf[0:n]);
- i = inst.next().index();
+ n := utf8.EncodeRune(inst.(*_Char).char, utf)
+ b = bytes.Add(b, utf[0:n])
+ i = inst.next().index()
}
// point start instruction to first non-CHAR
- re.inst.At(0).(instr).setNext(re.inst.At(i).(instr));
- re.prefixBytes = b;
- re.prefix = string(b);
+ re.inst.At(0).(instr).setNext(re.inst.At(i).(instr))
+ re.prefixBytes = b
+ re.prefix = string(b)
}
// Compile parses a regular expression and returns, if successful, a Regexp
// object that can be used to match against text.
func Compile(str string) (regexp *Regexp, error os.Error) {
- regexp = new(Regexp);
- regexp.expr = str;
- regexp.inst = new(vector.Vector);
- error = regexp.doParse();
- return;
+ regexp = new(Regexp)
+ regexp.expr = str
+ regexp.inst = new(vector.Vector)
+ error = regexp.doParse()
+ return
}
// MustCompile is like Compile but panics if the expression cannot be parsed.
// It simplifies safe initialization of global variables holding compiled regular
// expressions.
func MustCompile(str string) *Regexp {
- regexp, error := Compile(str);
+ regexp, error := Compile(str)
if error != nil {
panicln(`regexp: compiling "`, str, `": `, error.String())
}
- return regexp;
+ return regexp
}
// The match arena allows us to reduce the garbage generated by tossing
// match vectors away as we execute. Matches are ref counted and returned
// to a free list when no longer active. Increases a simple benchmark by 22X.
type matchArena struct {
- head *matchVec;
- len int; // length of match vector
+ head *matchVec
+ len int // length of match vector
}
type matchVec struct {
- m []int; // pairs of bracketing submatches. 0th is start,end
- ref int;
- next *matchVec;
+ m []int // pairs of bracketing submatches. 0th is start,end
+ ref int
+ next *matchVec
}
func (a *matchArena) new() *matchVec {
if a.head == nil {
- const N = 10;
- block := make([]matchVec, N);
+ const N = 10
+ block := make([]matchVec, N)
for i := 0; i < N; i++ {
- b := &block[i];
- b.next = a.head;
- a.head = b;
+ b := &block[i]
+ b.next = a.head
+ a.head = b
}
}
- m := a.head;
- a.head = m.next;
- m.ref = 0;
+ m := a.head
+ a.head = m.next
+ m.ref = 0
if m.m == nil {
m.m = make([]int, a.len)
}
- return m;
+ return m
}
func (a *matchArena) free(m *matchVec) {
- m.ref--;
+ m.ref--
if m.ref == 0 {
- m.next = a.head;
- a.head = m;
+ m.next = a.head
+ a.head = m
}
}
func (a *matchArena) copy(m *matchVec) *matchVec {
- m1 := a.new();
- copy(m1.m, m.m);
- return m1;
+ m1 := a.new()
+ copy(m1.m, m.m)
+ return m1
}
func (a *matchArena) noMatch() *matchVec {
- m := a.new();
+ m := a.new()
for i := range m.m {
- m.m[i] = -1 // no match seen; catches cases like "a(b)?c" on "ac"
+ m.m[i] = -1 // no match seen; catches cases like "a(b)?c" on "ac"
}
- m.ref = 1;
- return m;
+ m.ref = 1
+ return m
}
type state struct {
- inst instr; // next instruction to execute
- match *matchVec;
+ inst instr // next instruction to execute
+ match *matchVec
}
// Append new state to to-do list. Leftmost-longest wins so avoid
@@ -747,25 +747,25 @@ func (a *matchArena) addState(s []state, inst instr, match *matchVec, pos, end i
if pos == 0 {
s = a.addState(s, inst.next(), match, pos, end)
}
- return s;
+ return s
case _EOT:
if pos == end {
s = a.addState(s, inst.next(), match, pos, end)
}
- return s;
+ return s
case _BRA:
- n := inst.(*_Bra).n;
- match.m[2*n] = pos;
- s = a.addState(s, inst.next(), match, pos, end);
- return s;
+ n := inst.(*_Bra).n
+ match.m[2*n] = pos
+ s = a.addState(s, inst.next(), match, pos, end)
+ return s
case _EBRA:
- n := inst.(*_Ebra).n;
- match.m[2*n+1] = pos;
- s = a.addState(s, inst.next(), match, pos, end);
- return s;
+ n := inst.(*_Ebra).n
+ match.m[2*n+1] = pos
+ s = a.addState(s, inst.next(), match, pos, end)
+ return s
}
- index := inst.index();
- l := len(s);
+ index := inst.index()
+ l := len(s)
// States are inserted in order so it's sufficient to see if we have the same
// instruction; no need to see if existing match is earlier (it is).
for i := 0; i < l; i++ {
@@ -774,38 +774,38 @@ func (a *matchArena) addState(s []state, inst instr, match *matchVec, pos, end i
}
}
if l == cap(s) {
- s1 := make([]state, 2*l)[0:l];
- copy(s1, s);
- s = s1;
+ s1 := make([]state, 2*l)[0:l]
+ copy(s1, s)
+ s = s1
}
- s = s[0 : l+1];
- s[l].inst = inst;
- s[l].match = match;
- match.ref++;
+ s = s[0 : l+1]
+ s[l].inst = inst
+ s[l].match = match
+ match.ref++
if inst.kind() == _ALT {
- s = a.addState(s, inst.(*_Alt).left, a.copy(match), pos, end);
+ s = a.addState(s, inst.(*_Alt).left, a.copy(match), pos, end)
// give other branch a copy of this match vector
- s = a.addState(s, inst.next(), a.copy(match), pos, end);
+ s = a.addState(s, inst.next(), a.copy(match), pos, end)
}
- return s;
+ return s
}
// Accepts either string or bytes - the logic is identical either way.
// If bytes == nil, scan str.
func (re *Regexp) doExecute(str string, bytestr []byte, pos int) []int {
- var s [2][]state;
- s[0] = make([]state, 10)[0:0];
- s[1] = make([]state, 10)[0:0];
- in, out := 0, 1;
- var final state;
- found := false;
- end := len(str);
+ var s [2][]state
+ s[0] = make([]state, 10)[0:0]
+ s[1] = make([]state, 10)[0:0]
+ in, out := 0, 1
+ var final state
+ found := false
+ end := len(str)
if bytestr != nil {
end = len(bytestr)
}
// fast check for initial plain substring
if re.prefix != "" {
- var advance int;
+ var advance int
if bytestr == nil {
advance = strings.Index(str[pos:], re.prefix)
} else {
@@ -814,30 +814,30 @@ func (re *Regexp) doExecute(str string, bytestr []byte, pos int) []int {
if advance == -1 {
return []int{}
}
- pos += advance + len(re.prefix);
+ pos += advance + len(re.prefix)
}
- arena := &matchArena{nil, 2 * (re.nbra + 1)};
+ arena := &matchArena{nil, 2 * (re.nbra + 1)}
for pos <= end {
if !found {
// prime the pump if we haven't seen a match yet
- match := arena.noMatch();
- match.m[0] = pos;
- s[out] = arena.addState(s[out], re.start.next(), match, pos, end);
- arena.free(match); // if addState saved it, ref was incremented
+ match := arena.noMatch()
+ match.m[0] = pos
+ s[out] = arena.addState(s[out], re.start.next(), match, pos, end)
+ arena.free(match) // if addState saved it, ref was incremented
}
- in, out = out, in; // old out state is new in state
+ in, out = out, in // old out state is new in state
// clear out old state
- old := s[out];
+ old := s[out]
for _, state := range old {
arena.free(state.match)
}
- s[out] = old[0:0]; // truncate state vector
+ s[out] = old[0:0] // truncate state vector
if found && len(s[in]) == 0 {
// machine has completed
break
}
- charwidth := 1;
- c := endOfFile;
+ charwidth := 1
+ c := endOfFile
if pos < end {
if bytestr == nil {
c, charwidth = utf8.DecodeRuneInString(str[pos:end])
@@ -845,7 +845,7 @@ func (re *Regexp) doExecute(str string, bytestr []byte, pos int) []int {
c, charwidth = utf8.DecodeRune(bytestr[pos:end])
}
}
- pos += charwidth;
+ pos += charwidth
for _, st := range s[in] {
switch st.inst.kind() {
case _BOT:
@@ -871,20 +871,20 @@ func (re *Regexp) doExecute(str string, bytestr []byte, pos int) []int {
case _ALT:
case _END:
// choose leftmost longest
- if !found || // first
- st.match.m[0] < final.match.m[0] || // leftmost
- (st.match.m[0] == final.match.m[0] && pos-charwidth > final.match.m[1]) { // longest
+ if !found || // first
+ st.match.m[0] < final.match.m[0] || // leftmost
+ (st.match.m[0] == final.match.m[0] && pos-charwidth > final.match.m[1]) { // longest
if final.match != nil {
arena.free(final.match)
}
- final = st;
- final.match.ref++;
- final.match.m[1] = pos - charwidth;
+ final = st
+ final.match.ref++
+ final.match.m[1] = pos - charwidth
}
- found = true;
+ found = true
default:
- st.inst.print();
- panic("unknown instruction in execute");
+ st.inst.print()
+ panic("unknown instruction in execute")
}
}
}
@@ -895,7 +895,7 @@ func (re *Regexp) doExecute(str string, bytestr []byte, pos int) []int {
if re.prefix != "" && len(final.match.m) > 0 {
final.match.m[0] -= len(re.prefix)
}
- return final.match.m;
+ return final.match.m
}
@@ -918,17 +918,17 @@ func (re *Regexp) ExecuteString(s string) (a []int) {
// b[a[2*i]:a[2*i+1]] for i > 0 is the subslice matched by the ith parenthesized subexpression.
// A negative value means the subexpression did not match any element of the slice.
// An empty array means "no match".
-func (re *Regexp) Execute(b []byte) (a []int) { return re.doExecute("", b, 0) }
+func (re *Regexp) Execute(b []byte) (a []int) { return re.doExecute("", b, 0) }
// MatchString returns whether the Regexp matches the string s.
// The return value is a boolean: true for match, false for no match.
-func (re *Regexp) MatchString(s string) bool { return len(re.doExecute(s, nil, 0)) > 0 }
+func (re *Regexp) MatchString(s string) bool { return len(re.doExecute(s, nil, 0)) > 0 }
// Match returns whether the Regexp matches the byte slice b.
// The return value is a boolean: true for match, false for no match.
-func (re *Regexp) Match(b []byte) bool { return len(re.doExecute("", b, 0)) > 0 }
+func (re *Regexp) Match(b []byte) bool { return len(re.doExecute("", b, 0)) > 0 }
// MatchStrings matches the Regexp against the string s.
@@ -937,17 +937,17 @@ func (re *Regexp) Match(b []byte) bool { return len(re.doExecute("", b, 0)) > 0
// a[i] for i > 0 is the substring matched by the ith parenthesized subexpression.
// An empty array means ``no match''.
func (re *Regexp) MatchStrings(s string) (a []string) {
- r := re.doExecute(s, nil, 0);
+ r := re.doExecute(s, nil, 0)
if r == nil {
return nil
}
- a = make([]string, len(r)/2);
+ a = make([]string, len(r)/2)
for i := 0; i < len(r); i += 2 {
- if r[i] != -1 { // -1 means no match for this subexpression
+ if r[i] != -1 { // -1 means no match for this subexpression
a[i/2] = s[r[i]:r[i+1]]
}
}
- return;
+ return
}
// MatchSlices matches the Regexp against the byte slice b.
@@ -956,56 +956,56 @@ func (re *Regexp) MatchStrings(s string) (a []string) {
// a[i] for i > 0 is the subslice matched by the ith parenthesized subexpression.
// An empty array means ``no match''.
func (re *Regexp) MatchSlices(b []byte) (a [][]byte) {
- r := re.doExecute("", b, 0);
+ r := re.doExecute("", b, 0)
if r == nil {
return nil
}
- a = make([][]byte, len(r)/2);
+ a = make([][]byte, len(r)/2)
for i := 0; i < len(r); i += 2 {
- if r[i] != -1 { // -1 means no match for this subexpression
+ if r[i] != -1 { // -1 means no match for this subexpression
a[i/2] = b[r[i]:r[i+1]]
}
}
- return;
+ return
}
// MatchString checks whether a textual regular expression
// matches a string. More complicated queries need
// to use Compile and the full Regexp interface.
func MatchString(pattern string, s string) (matched bool, error os.Error) {
- re, err := Compile(pattern);
+ re, err := Compile(pattern)
if err != nil {
return false, err
}
- return re.MatchString(s), nil;
+ return re.MatchString(s), nil
}
// Match checks whether a textual regular expression
// matches a byte slice. More complicated queries need
// to use Compile and the full Regexp interface.
func Match(pattern string, b []byte) (matched bool, error os.Error) {
- re, err := Compile(pattern);
+ re, err := Compile(pattern)
if err != nil {
return false, err
}
- return re.Match(b), nil;
+ return re.Match(b), nil
}
// ReplaceAllString returns a copy of src in which all matches for the Regexp
// have been replaced by repl. No support is provided for expressions
// (e.g. \1 or $1) in the replacement string.
func (re *Regexp) ReplaceAllString(src, repl string) string {
- lastMatchEnd := 0; // end position of the most recent match
- searchPos := 0; // position where we next look for a match
- buf := new(bytes.Buffer);
+ lastMatchEnd := 0 // end position of the most recent match
+ searchPos := 0 // position where we next look for a match
+ buf := new(bytes.Buffer)
for searchPos <= len(src) {
- a := re.doExecute(src, nil, searchPos);
+ a := re.doExecute(src, nil, searchPos)
if len(a) == 0 {
- break // no more matches
+ break // no more matches
}
// Copy the unmatched characters before this match.
- io.WriteString(buf, src[lastMatchEnd:a[0]]);
+ io.WriteString(buf, src[lastMatchEnd:a[0]])
// Now insert a copy of the replacement string, but not for a
// match of the empty string immediately after another match.
@@ -1014,10 +1014,10 @@ func (re *Regexp) ReplaceAllString(src, repl string) string {
if a[1] > lastMatchEnd || a[0] == 0 {
io.WriteString(buf, repl)
}
- lastMatchEnd = a[1];
+ lastMatchEnd = a[1]
// Advance past this match; always advance at least one character.
- _, width := utf8.DecodeRuneInString(src[searchPos:]);
+ _, width := utf8.DecodeRuneInString(src[searchPos:])
if searchPos+width > a[1] {
searchPos += width
} else if searchPos+1 > a[1] {
@@ -1030,26 +1030,26 @@ func (re *Regexp) ReplaceAllString(src, repl string) string {
}
// Copy the unmatched characters after the last match.
- io.WriteString(buf, src[lastMatchEnd:]);
+ io.WriteString(buf, src[lastMatchEnd:])
- return buf.String();
+ return buf.String()
}
// ReplaceAll returns a copy of src in which all matches for the Regexp
// have been replaced by repl. No support is provided for expressions
// (e.g. \1 or $1) in the replacement text.
func (re *Regexp) ReplaceAll(src, repl []byte) []byte {
- lastMatchEnd := 0; // end position of the most recent match
- searchPos := 0; // position where we next look for a match
- buf := new(bytes.Buffer);
+ lastMatchEnd := 0 // end position of the most recent match
+ searchPos := 0 // position where we next look for a match
+ buf := new(bytes.Buffer)
for searchPos <= len(src) {
- a := re.doExecute("", src, searchPos);
+ a := re.doExecute("", src, searchPos)
if len(a) == 0 {
- break // no more matches
+ break // no more matches
}
// Copy the unmatched characters before this match.
- buf.Write(src[lastMatchEnd:a[0]]);
+ buf.Write(src[lastMatchEnd:a[0]])
// Now insert a copy of the replacement string, but not for a
// match of the empty string immediately after another match.
@@ -1058,10 +1058,10 @@ func (re *Regexp) ReplaceAll(src, repl []byte) []byte {
if a[1] > lastMatchEnd || a[0] == 0 {
buf.Write(repl)
}
- lastMatchEnd = a[1];
+ lastMatchEnd = a[1]
// Advance past this match; always advance at least one character.
- _, width := utf8.DecodeRune(src[searchPos:]);
+ _, width := utf8.DecodeRune(src[searchPos:])
if searchPos+width > a[1] {
searchPos += width
} else if searchPos+1 > a[1] {
@@ -1074,33 +1074,33 @@ func (re *Regexp) ReplaceAll(src, repl []byte) []byte {
}
// Copy the unmatched characters after the last match.
- buf.Write(src[lastMatchEnd:]);
+ buf.Write(src[lastMatchEnd:])
- return buf.Bytes();
+ return buf.Bytes()
}
// QuoteMeta returns a string that quotes all regular expression metacharacters
// inside the argument text; the returned string is a regular expression matching
// the literal text. For example, QuoteMeta(`[foo]`) returns `\[foo\]`.
func QuoteMeta(s string) string {
- b := make([]byte, 2*len(s));
+ b := make([]byte, 2*len(s))
// A byte loop is correct because all metacharacters are ASCII.
- j := 0;
+ j := 0
for i := 0; i < len(s); i++ {
if special(int(s[i])) {
- b[j] = '\\';
- j++;
+ b[j] = '\\'
+ j++
}
- b[j] = s[i];
- j++;
+ b[j] = s[i]
+ j++
}
- return string(b[0:j]);
+ return string(b[0:j])
}
// Find matches in slice b if b is non-nil, otherwise find matches in string s.
func (re *Regexp) allMatches(s string, b []byte, n int, deliver func(int, int)) {
- var end int;
+ var end int
if b == nil {
end = len(s)
} else {
@@ -1108,12 +1108,12 @@ func (re *Regexp) allMatches(s string, b []byte, n int, deliver func(int, int))
}
for pos, i, prevMatchEnd := 0, 0, -1; i < n && pos <= end; {
- matches := re.doExecute(s, b, pos);
+ matches := re.doExecute(s, b, pos)
if len(matches) == 0 {
break
}
- accept := true;
+ accept := true
if matches[1] == pos {
// We've found an empty match.
if matches[0] == prevMatchEnd {
@@ -1121,7 +1121,7 @@ func (re *Regexp) allMatches(s string, b []byte, n int, deliver func(int, int))
// after a previous match, so ignore it.
accept = false
}
- var width int;
+ var width int
if b == nil {
_, width = utf8.DecodeRuneInString(s[pos:end])
} else {
@@ -1135,11 +1135,11 @@ func (re *Regexp) allMatches(s string, b []byte, n int, deliver func(int, int))
} else {
pos = matches[1]
}
- prevMatchEnd = matches[1];
+ prevMatchEnd = matches[1]
if accept {
- deliver(matches[0], matches[1]);
- i++;
+ deliver(matches[0], matches[1])
+ i++
}
}
}
@@ -1153,13 +1153,13 @@ func (re *Regexp) AllMatches(b []byte, n int) [][]byte {
if n <= 0 {
n = len(b) + 1
}
- result := make([][]byte, n);
- i := 0;
+ result := make([][]byte, n)
+ i := 0
re.allMatches("", b, n, func(start, end int) {
- result[i] = b[start:end];
- i++;
- });
- return result[0:i];
+ result[i] = b[start:end]
+ i++
+ })
+ return result[0:i]
}
// AllMatchesString slices the string s into substrings that are successive
@@ -1171,13 +1171,13 @@ func (re *Regexp) AllMatchesString(s string, n int) []string {
if n <= 0 {
n = len(s) + 1
}
- result := make([]string, n);
- i := 0;
+ result := make([]string, n)
+ i := 0
re.allMatches(s, nil, n, func(start, end int) {
- result[i] = s[start:end];
- i++;
- });
- return result[0:i];
+ result[i] = s[start:end]
+ i++
+ })
+ return result[0:i]
}
// AllMatchesIter slices the byte slice b into substrings that are successive
@@ -1189,12 +1189,12 @@ func (re *Regexp) AllMatchesIter(b []byte, n int) <-chan []byte {
if n <= 0 {
n = len(b) + 1
}
- c := make(chan []byte, 10);
+ c := make(chan []byte, 10)
go func() {
- re.allMatches("", b, n, func(start, end int) { c <- b[start:end] });
- close(c);
- }();
- return c;
+ re.allMatches("", b, n, func(start, end int) { c <- b[start:end] })
+ close(c)
+ }()
+ return c
}
// AllMatchesStringIter slices the string s into substrings that are successive
@@ -1206,10 +1206,10 @@ func (re *Regexp) AllMatchesStringIter(s string, n int) <-chan string {
if n <= 0 {
n = len(s) + 1
}
- c := make(chan string, 10);
+ c := make(chan string, 10)
go func() {
- re.allMatches(s, nil, n, func(start, end int) { c <- s[start:end] });
- close(c);
- }();
- return c;
+ re.allMatches(s, nil, n, func(start, end int) { c <- s[start:end] })
+ close(c)
+ }()
+ return c
}