Negative look-ahead in Go regular expressions

33,988

Solution 1

Negative lookahead isn't supported for technical reasons, specifically because it conflicts with the O(n)-time guarantees of the library. See the golang-nuts group discussion about this, as well as the Caveats section in Regular Expression Matching in the Wild.

You can express the regular expression you've described without negative lookahead:

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

Here's an example to demonstrate:

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))
}

Solution 2

dlclark/regexp2 is a port of the .NET framework's System.Text.RegularExpressions.Regex engine.

There are some fundamental differences between .NET strings and Go strings that required a bit of borrowing from the Go framework regex engine as well. I cleaned up a couple of the dirtier bits during the port (regexcharclass.cs was terrible), but the parse tree, code emmitted, and therefore patterns matched should be identical.

It's name dropped at the end of the lengthy discussion about O(n) regular expressions, and is caveated:

However, I would advise caution as there are benefits to the re2-based engine that are not provided by more full featured engines with lookarounds. If you have the option then stick with the stdlib.

The cost of features is a slower implementation.

Solution 3

Based off your examples and your expected output, the following would work.

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

GoPlay

Share:
33,988

Related videos on Youtube

K2xL
Author by

K2xL

python, go, php, node/javascript, ruby, java, and general web development is what i do

Updated on October 11, 2020

Comments

  • K2xL
    K2xL over 3 years

    I'm trying to use negative look-aheads in Go.

    The following regular expression: BBB(((?!BBB).)*)EEE

    http://rubular.com/r/Zw1vopp1MF

    However, in Go I get:

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

    Are there any alternatives?

    • hwnd
      hwnd over 9 years
      What's your expected output that you want?
    • K2xL
      K2xL over 9 years
      I want to match everything in between a BBB and EEE. However, if there is an instance with BBB something BBB something else EEE . I only want to match "BBB something else EEE"
    • vks
      vks over 9 years
      Only thing you can do is regex101.com/r/aM5oU3/4 if you are very sure that standalone B or BB is not there in the string.
    • twotwotwo
      twotwotwo over 9 years
      If you can, use the answer, because life is easier with just the Go stdlib. (Fewer compilation and distribution headaches and other cgo issues.) If you badly need Perl-compatible regexps for some reason, you could look at one of the PCRE adapters out there, like github.com/glenn-brown/golang-pkg-pcre
  • dyoo
    dyoo over 9 years
    @hwnd's solution is simpler. I'm assuming that when you say BBB, you don't really mean BBB literally, but rather some arbitrary sequence of Beginning characters, followed by a sequence of Ending characters. But perhaps you are looking for "BBB" and "EEE". :P
  • femtoRgon
    femtoRgon over 9 years
    Seems that this would fail for something like: BBB xx B xx EEE
  • Radek Simko
    Radek Simko almost 9 years
    It may be a solution, but to a different question. The question was about negative lookahead.
  • hwnd
    hwnd almost 9 years
    Yes, which is not supported.
  • napolux
    napolux about 5 years
    Hey, this is brilliant!