mirror of
https://github.com/golang/go
synced 2024-11-23 08:10:03 -07:00
regexp/syntax: accept (?<name>...) syntax as valid capture
Currently the only named capture supported by regexp is (?P<name>a).
The syntax (?<name>a) is also widely used and there is currently an effort from
the Rust regex and RE2 teams to also accept this syntax.
Fixes #58458
Change-Id: If22d44d3a5c4e8133ec68238ab130c151ca7c5c5
GitHub-Last-Rev: 31b50e6ab4
GitHub-Pull-Request: golang/go#61624
Reviewed-on: https://go-review.googlesource.com/c/go/+/513838
Auto-Submit: Ian Lance Taylor <iant@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: David Chase <drchase@google.com>
Run-TryBot: Ian Lance Taylor <iant@google.com>
Reviewed-by: Ian Lance Taylor <iant@google.com>
This commit is contained in:
parent
977e23a707
commit
ee61186b33
@ -56,6 +56,7 @@ Grouping:
|
|||||||
|
|
||||||
(re) numbered capturing group (submatch)
|
(re) numbered capturing group (submatch)
|
||||||
(?P<name>re) named & numbered capturing group (submatch)
|
(?P<name>re) named & numbered capturing group (submatch)
|
||||||
|
(?<name>re) named & numbered capturing group (submatch)
|
||||||
(?:re) non-capturing group
|
(?:re) non-capturing group
|
||||||
(?flags) set flags within current group; non-capturing
|
(?flags) set flags within current group; non-capturing
|
||||||
(?flags:re) set flags during re; non-capturing
|
(?flags:re) set flags during re; non-capturing
|
||||||
|
@ -1159,9 +1159,18 @@ func (p *parser) parsePerlFlags(s string) (rest string, err error) {
|
|||||||
// support all three as well. EcmaScript 4 uses only the Python form.
|
// support all three as well. EcmaScript 4 uses only the Python form.
|
||||||
//
|
//
|
||||||
// In both the open source world (via Code Search) and the
|
// In both the open source world (via Code Search) and the
|
||||||
// Google source tree, (?P<expr>name) is the dominant form,
|
// Google source tree, (?P<expr>name) and (?<expr>name) are the
|
||||||
// so that's the one we implement. One is enough.
|
// dominant forms of named captures and both are supported.
|
||||||
if len(t) > 4 && t[2] == 'P' && t[3] == '<' {
|
startsWithP := len(t) > 4 && t[2] == 'P' && t[3] == '<'
|
||||||
|
startsWithName := len(t) > 3 && t[2] == '<'
|
||||||
|
|
||||||
|
if startsWithP || startsWithName {
|
||||||
|
// position of expr start
|
||||||
|
exprStartPos := 4
|
||||||
|
if startsWithName {
|
||||||
|
exprStartPos = 3
|
||||||
|
}
|
||||||
|
|
||||||
// Pull out name.
|
// Pull out name.
|
||||||
end := strings.IndexRune(t, '>')
|
end := strings.IndexRune(t, '>')
|
||||||
if end < 0 {
|
if end < 0 {
|
||||||
@ -1171,8 +1180,8 @@ func (p *parser) parsePerlFlags(s string) (rest string, err error) {
|
|||||||
return "", &Error{ErrInvalidNamedCapture, s}
|
return "", &Error{ErrInvalidNamedCapture, s}
|
||||||
}
|
}
|
||||||
|
|
||||||
capture := t[:end+1] // "(?P<name>"
|
capture := t[:end+1] // "(?P<name>" or "(?<name>"
|
||||||
name := t[4:end] // "name"
|
name := t[exprStartPos:end] // "name"
|
||||||
if err = checkUTF8(name); err != nil {
|
if err = checkUTF8(name); err != nil {
|
||||||
return "", err
|
return "", err
|
||||||
}
|
}
|
||||||
|
@ -160,6 +160,7 @@ var parseTests = []parseTest{
|
|||||||
|
|
||||||
// Test named captures
|
// Test named captures
|
||||||
{`(?P<name>a)`, `cap{name:lit{a}}`},
|
{`(?P<name>a)`, `cap{name:lit{a}}`},
|
||||||
|
{`(?<name>a)`, `cap{name:lit{a}}`},
|
||||||
|
|
||||||
// Case-folded literals
|
// Case-folded literals
|
||||||
{`[Aa]`, `litfold{A}`},
|
{`[Aa]`, `litfold{A}`},
|
||||||
@ -482,6 +483,11 @@ var invalidRegexps = []string{
|
|||||||
`(?P<name`,
|
`(?P<name`,
|
||||||
`(?P<x y>a)`,
|
`(?P<x y>a)`,
|
||||||
`(?P<>a)`,
|
`(?P<>a)`,
|
||||||
|
`(?<name>a`,
|
||||||
|
`(?<name>`,
|
||||||
|
`(?<name`,
|
||||||
|
`(?<x y>a)`,
|
||||||
|
`(?<>a)`,
|
||||||
`[a-Z]`,
|
`[a-Z]`,
|
||||||
`(?i)[a-Z]`,
|
`(?i)[a-Z]`,
|
||||||
`\Q\E*`,
|
`\Q\E*`,
|
||||||
|
Loading…
Reference in New Issue
Block a user