我正在尝试想出一个正则表达式,它允许我匹配具有相等部分和它们之间的分隔符的字符串。例如:
foo;foo <- match
foobar;foobar <- match
foo;foobar <- no match
foo;bar <- no match
这可以通过使用积极的前瞻断言通过 PCRE 轻松完成:
([^;]+);(?=\1$)
问题是,我需要使用 Re2 库用 Go 编写的程序,该库不支持环视断言。我无法更改代码,我只能使用正则表达式字符串来提供它。
恐怕这个问题仅靠正则表达式无法解决。所以我有两个解决方案给你。
注意:如果字符串仅包含一个分隔符,则此解决方案有效。
package main
import (
"fmt"
"regexp"
)
func regexMatch(str string) bool {
pattern1 := regexp.MustCompile(`^([^;]+);`)
pattern2 := regexp.MustCompile(`;([^;]+)$`)
match1 := pattern1.FindString(str)
match2 := pattern2.FindString(str)
return match1[:len(match1)-1] == match2[1:]
}
func main() {
fmt.Println(regexMatch("foo;foo")) // true
fmt.Println(regexMatch("foobar;foobar")) // true
fmt.Println(regexMatch("foo;foobar")) // false
fmt.Println(regexMatch("foo;bar")) // false
}
此解决方案更加紧凑,如果分隔符可以多个,您可以轻松更改逻辑。
package main
import (
"fmt"
"strings"
)
func splitMatch(str string) bool {
matches := strings.Split(str, ";")
if (len(matches) != 2) {
return false
}
return matches[0] == matches[1]
}
func main() {
fmt.Println(splitMatch("foo;foo")) // true
fmt.Println(splitMatch("foobar;foobar")) // true
fmt.Println(splitMatch("foo;foobar")) // false
fmt.Println(splitMatch("foo;bar")) // false
}
^([a-z]+);(\1)$
^
:断言字符串的开头。([a-z]+)
:这是一个捕获组,匹配从 +
到 a
的一个或多个 (z
) 小写字母。;
:字面上匹配分号字符;
。这充当字符串两部分之间的分隔符。(\1)
:这是对第一个捕获组的反向引用。这意味着第一个捕获组中匹配的任何内容都必须在此处完全相同。$
:断言字符串结尾。