mirror of
https://github.com/golang/go
synced 2024-11-23 16:20:04 -07:00
regexp: add (*Regexp).SubexpIndex
SubexpIndex returns the index of the first subexpression with the given name, or -1 if there is no subexpression with that name. Fixes #32420 Change-Id: Ie1f9d22d50fb84e18added80a9d9a9f6dca8ffc4 Reviewed-on: https://go-review.googlesource.com/c/go/+/187919 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Daniel Martí <mvdan@mvdan.cc>
This commit is contained in:
parent
245409ea86
commit
782fcb44b9
@ -418,24 +418,32 @@ func TestLiteralPrefix(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
type subexpCase struct {
|
||||
input string
|
||||
num int
|
||||
names []string
|
||||
type subexpIndex struct {
|
||||
name string
|
||||
index int
|
||||
}
|
||||
|
||||
type subexpCase struct {
|
||||
input string
|
||||
num int
|
||||
names []string
|
||||
indices []subexpIndex
|
||||
}
|
||||
|
||||
var emptySubexpIndices = []subexpIndex{{"", -1}, {"missing", -1}}
|
||||
|
||||
var subexpCases = []subexpCase{
|
||||
{``, 0, nil},
|
||||
{`.*`, 0, nil},
|
||||
{`abba`, 0, nil},
|
||||
{`ab(b)a`, 1, []string{"", ""}},
|
||||
{`ab(.*)a`, 1, []string{"", ""}},
|
||||
{`(.*)ab(.*)a`, 2, []string{"", "", ""}},
|
||||
{`(.*)(ab)(.*)a`, 3, []string{"", "", "", ""}},
|
||||
{`(.*)((a)b)(.*)a`, 4, []string{"", "", "", "", ""}},
|
||||
{`(.*)(\(ab)(.*)a`, 3, []string{"", "", "", ""}},
|
||||
{`(.*)(\(a\)b)(.*)a`, 3, []string{"", "", "", ""}},
|
||||
{`(?P<foo>.*)(?P<bar>(a)b)(?P<foo>.*)a`, 4, []string{"", "foo", "bar", "", "foo"}},
|
||||
{``, 0, nil, emptySubexpIndices},
|
||||
{`.*`, 0, nil, emptySubexpIndices},
|
||||
{`abba`, 0, nil, emptySubexpIndices},
|
||||
{`ab(b)a`, 1, []string{"", ""}, emptySubexpIndices},
|
||||
{`ab(.*)a`, 1, []string{"", ""}, emptySubexpIndices},
|
||||
{`(.*)ab(.*)a`, 2, []string{"", "", ""}, emptySubexpIndices},
|
||||
{`(.*)(ab)(.*)a`, 3, []string{"", "", "", ""}, emptySubexpIndices},
|
||||
{`(.*)((a)b)(.*)a`, 4, []string{"", "", "", "", ""}, emptySubexpIndices},
|
||||
{`(.*)(\(ab)(.*)a`, 3, []string{"", "", "", ""}, emptySubexpIndices},
|
||||
{`(.*)(\(a\)b)(.*)a`, 3, []string{"", "", "", ""}, emptySubexpIndices},
|
||||
{`(?P<foo>.*)(?P<bar>(a)b)(?P<foo>.*)a`, 4, []string{"", "foo", "bar", "", "foo"}, []subexpIndex{{"", -1}, {"missing", -1}, {"foo", 1}, {"bar", 2}}},
|
||||
}
|
||||
|
||||
func TestSubexp(t *testing.T) {
|
||||
@ -458,6 +466,12 @@ func TestSubexp(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
for _, subexp := range c.indices {
|
||||
index := re.SubexpIndex(subexp.name)
|
||||
if index != subexp.index {
|
||||
t.Errorf("%q: SubexpIndex(%q) = %d, want %d", c.input, subexp.name, index, subexp.index)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -280,6 +280,19 @@ func ExampleRegexp_SubexpNames() {
|
||||
// Turing Alan
|
||||
}
|
||||
|
||||
func ExampleRegexp_SubexpIndex() {
|
||||
re := regexp.MustCompile(`(?P<first>[a-zA-Z]+) (?P<last>[a-zA-Z]+)`)
|
||||
fmt.Println(re.MatchString("Alan Turing"))
|
||||
matches := re.FindStringSubmatch("Alan Turing")
|
||||
lastIndex := re.SubexpIndex("last")
|
||||
fmt.Printf("last => %d\n", lastIndex)
|
||||
fmt.Println(matches[lastIndex])
|
||||
// Output:
|
||||
// true
|
||||
// last => 2
|
||||
// Turing
|
||||
}
|
||||
|
||||
func ExampleRegexp_Split() {
|
||||
a := regexp.MustCompile(`a`)
|
||||
fmt.Println(a.Split("banana", -1))
|
||||
|
@ -345,6 +345,24 @@ func (re *Regexp) SubexpNames() []string {
|
||||
return re.subexpNames
|
||||
}
|
||||
|
||||
// SubexpIndex returns the index of the first subexpression with the given name,
|
||||
// or -1 if there is no subexpression with that name.
|
||||
//
|
||||
// Note that multiple subexpressions can be written using the same name, as in
|
||||
// (?P<bob>a+)(?P<bob>b+), which declares two subexpressions named "bob".
|
||||
// In this case, SubexpIndex returns the index of the leftmost such subexpression
|
||||
// in the regular expression.
|
||||
func (re *Regexp) SubexpIndex(name string) int {
|
||||
if name != "" {
|
||||
for i, s := range re.subexpNames {
|
||||
if name == s {
|
||||
return i
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
const endOfText rune = -1
|
||||
|
||||
// input abstracts different representations of the input text. It provides
|
||||
|
Loading…
Reference in New Issue
Block a user