4 Commits

3 changed files with 41 additions and 8 deletions

View File

@@ -165,7 +165,10 @@ func shuntingYard(re string, flags ...ReFlag) ([]postfixNode, error) {
var rangeStart int var rangeStart int
var rangeEnd int var rangeEnd int
fmt.Sscanf(tmpStr, "%d-%d", &rangeStart, &rangeEnd) fmt.Sscanf(tmpStr, "%d-%d", &rangeStart, &rangeEnd)
regex := range2regex(rangeStart, rangeEnd) regex, err := range2regex(rangeStart, rangeEnd)
if err != nil {
return nil, err
}
re_runes = append(re_runes, []rune(regex)...) re_runes = append(re_runes, []rune(regex)...)
} else if c == '(' && i < len(re_runes_orig)-2 && re_runes_orig[i+1] == '?' && re_runes_orig[i+2] == ':' { } else if c == '(' && i < len(re_runes_orig)-2 && re_runes_orig[i+1] == '?' && re_runes_orig[i+2] == ':' {
re_runes = append(re_runes, NONCAPLPAREN_CHAR) re_runes = append(re_runes, NONCAPLPAREN_CHAR)

View File

@@ -44,11 +44,11 @@ func intToSlc(val int) []int {
return toRet return toRet
} }
func range2regex(start int, end int) string { func range2regex(start int, end int) (string, error) {
rangeStart := start rangeStart := start
rangeEnd := end rangeEnd := end
if rangeStart > rangeEnd { if rangeStart > rangeEnd {
panic("Range start greater than range end.") return "", fmt.Errorf("numeric range start greater than range end")
} }
ranges := make([]numRange, 0) ranges := make([]numRange, 0)
@@ -99,17 +99,17 @@ func range2regex(start int, end int) string {
// Last range - tmp to rangeEnd // Last range - tmp to rangeEnd
ranges = append(ranges, numRange{tmp, rangeEnd}) ranges = append(ranges, numRange{tmp, rangeEnd})
regex := "(" regex := string(NONCAPLPAREN_CHAR)
// Generate the regex // Generate the regex
for i, rg := range ranges { for i, rg := range ranges {
if i > 0 { if i > 0 {
regex += "|" regex += "|"
} }
regex += "(" regex += string(NONCAPLPAREN_CHAR)
startSlc := intToSlc(rg.start) startSlc := intToSlc(rg.start)
endSlc := intToSlc(rg.end) endSlc := intToSlc(rg.end)
if len(startSlc) != len(endSlc) { if len(startSlc) != len(endSlc) {
panic("Ranges have unequal lengths.") return "", fmt.Errorf("Error parsing numeric range")
} }
for i := range startSlc { for i := range startSlc {
if startSlc[i] == endSlc[i] { if startSlc[i] == endSlc[i] {
@@ -121,6 +121,6 @@ func range2regex(start int, end int) string {
regex += ")" regex += ")"
} }
regex += ")" regex += ")"
return regex return regex, nil
} }

View File

@@ -479,7 +479,35 @@ var reTests = []struct {
{`*?`, nil, `-`, nil}, {`*?`, nil, `-`, nil},
{`a*?`, nil, `-`, nil}, // non-greedy operators are not supported {`a*?`, nil, `-`, nil}, // non-greedy operators are not supported
// Todo - add numeric range tests // Numeric range tests - this is a feature that I added, and doesn't exist
// in any other mainstream regex engine
{`<0-255>`, nil, `0`, []Group{{0, 1}}},
{`<0-255>`, nil, `7`, []Group{{0, 1}}},
{`<0-255>`, nil, `46`, []Group{{0, 2}}},
{`<0-255>`, nil, `90`, []Group{{0, 2}}},
{`<0-255>`, nil, `107`, []Group{{0, 3}}},
{`<0-255>`, nil, `198`, []Group{{0, 3}}},
{`<0-255>`, nil, `254`, []Group{{0, 3}}},
{`<0-255>`, nil, `255`, []Group{{0, 3}}},
{`<0-255>`, nil, `256`, []Group{{0, 2}, {2, 3}}},
{`^<0-255>$`, nil, `256`, []Group{}},
{`^<0-299792458>$`, nil, `299000999`, []Group{{0, 9}}},
{`^<0-299792458>$`, nil, `299792531`, []Group{}},
{`^<3-0>$`, nil, `-`, nil},
{`^<0-0>$`, nil, `0`, []Group{{0, 1}}},
{`2<0-55>`, nil, `231`, []Group{{0, 3}}},
{`2<0-55>`, nil, `271`, []Group{{0, 2}}},
{`^2<0-55>$`, nil, `271`, []Group{}},
{`<389`, nil, `-`, nil},
{`<389>`, nil, `-`, nil},
{`<-389>`, nil, `-`, nil},
{`<389->`, nil, `-`, nil},
{`<389-400`, nil, `-`, nil},
{`<389-400>`, nil, `391`, []Group{{0, 3}}},
{`\b<1-10000>\b`, nil, `America declared independence in 1776.`, []Group{{33, 37}}},
} }
var groupTests = []struct { var groupTests = []struct {
@@ -634,6 +662,8 @@ var groupTests = []struct {
{`^([ab]*)(?=(b)?)c`, nil, `abc`, []Match{[]Group{{0, 3}, {0, 2}}}}, {`^([ab]*)(?=(b)?)c`, nil, `abc`, []Match{[]Group{{0, 3}, {0, 2}}}},
{`^([ab]*)(?!(b))c`, nil, `abc`, []Match{[]Group{{0, 3}, {0, 2}}}}, {`^([ab]*)(?!(b))c`, nil, `abc`, []Match{[]Group{{0, 3}, {0, 2}}}},
{`^([ab]*)(?<!(a))c`, nil, `abc`, []Match{[]Group{{0, 3}, {0, 2}}}}, {`^([ab]*)(?<!(a))c`, nil, `abc`, []Match{[]Group{{0, 3}, {0, 2}}}},
{`(<389-400>)`, nil, `391`, []Match{[]Group{{0, 3}, {0, 3}}}},
} }
func TestFindAllMatches(t *testing.T) { func TestFindAllMatches(t *testing.T) {