【问题标题】:Negative look-ahead in Go regular expressionsGo 正则表达式中的负前瞻
【发布时间】:2015-01-02 11:52:07
【问题描述】:

我正在尝试在 Go 中使用负前瞻。

以下正则表达式:BBB(((?!BBB).)*)EEE

http://rubular.com/r/Zw1vopp1MF

但是,在 Go 中我得到:

error parsing regexp: invalid or unsupported Perl syntax: `(?!`

还有其他选择吗?

【问题讨论】:

  • 您想要的预期输出是什么?
  • 我想匹配 BBB 和 EEE 之间的所有内容。但是,如果存在 BBB something BBB something else EEE 的实例。我只想匹配“BBB 其他 EEE”
  • 如果您非常确定独立的BBB 不在字符串中,那么您唯一能做的就是regex101.com/r/aM5oU3/4
  • 如果可以,请使用答案,因为仅使用 Go 标准库会更轻松。 (更少的编译和分发问题以及其他 cgo 问题。)如果您出于某种原因急需兼容 Perl 的正则表达式,您可以查看其中一个 PCRE 适配器,例如 github.com/glenn-brown/golang-pkg-pcre

标签: regex go regex-lookarounds


【解决方案1】:

由于技术原因,不支持负前瞻,特别是因为它与库的 O(n) 时间保证相冲突。请参阅golang-nuts group discussion 关于此内容以及Regular Expression Matching in the Wild 中的注意事项部分。

您可以表达您所描述的正则表达式而无需负前瞻:

BBB([^B]|B[^B]|BB[^B])*EEE

这里有一个example 来演示:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    re := regexp.MustCompile(`BBB([^B]|B[^B]|BB[^B])*EEE`)
    fmt.Printf("%#v\n", re.FindAllString("BBB EEE BBB..BBB...EEE", -1))
}

【讨论】:

  • @hwnd 的解决方案比较简单。我假设当你说BBB 时,你的意思并不是真正意义上的BBB,而是一些任意的开始字符序列,后跟一系列结束字符。但也许您正在寻找"BBB""EEE"。 :P
  • 嘿,这太棒了!
【解决方案2】:

dlclark/regexp2 是 .NET 框架的 System.Text.RegularExpressions.Regex 引擎的一个端口。

.NET 字符串和 Go 字符串之间存在一些根本差异,这也需要从 Go 框架正则表达式引擎中借用一点。我在移植期间清理了一些更脏的位(regexcharclass.cs 很糟糕),但是解析树、代码发出,因此匹配的模式应该是相同的。

它的名字放在lengthy discussion about O(n) regular expressions 的末尾,并且被警告:

但是,我建议您谨慎行事,因为基于 re2 的引擎有一些优点,这些优点是具有环视功能的更全功能的引擎所不具备的。如果你有选择,那么坚持使用标准库。

功能成本是实现速度较慢。

【讨论】:

    【解决方案3】:

    根据您的示例和您的预期输出,以下内容将起作用。

    re := regexp.MustCompile(`BBB([^B]*)EEE`)
    

    GoPlay

    【讨论】:

    • 似乎这会失败,例如:BBB xx B xx EEE
    • 这可能是一个解决方案,但针对不同的问题。问题是关于负前瞻。
    • 是的,不支持。
    猜你喜欢
    • 2021-10-11
    • 2011-10-14
    • 2010-12-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多