-1
package main

import "fmt"
import "regexp"

func main() {
    var sep = "=~"
    var filter = "exported_pod=~.*grafana.*"
    matched, _ := regexp.MatchString(sep+`\b`, filter)
    fmt.Println(matched)
}

In the above snippet, I'm trying to return True if =~ is exactly present in the filter string.

Unable to understand why it's returning false.

It works as expected if the filter string is "exported_pod=~grafana.*" whereas if it is "exported_pod=~.*grafana.*", it fails. Please help me in understanding what's wrong here.


The actual problem is:

Split the string around either =, =~, !=, !~.

In the example above, the result should be [ "exported_pod", ".*grafana.*" ].
But that split should happen for any one of the listed separators.

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
zubug55
  • 729
  • 7
  • 27
  • 1
    If you are looking for a literal `"=~"` use strings.Contains and not a regexp. – Volker May 25 '21 at 06:28
  • @Volker What should be the best way to test for =, =~, !=, !~ in the strings which can regex or non-regex? If I use string.contains("=") the problem is that it will match for string like this as well exported_pod=~.*grafana.*". (notice ~ here ). – zubug55 May 25 '21 at 08:16
  • I admit I have no idea what your actual problem is. What are "strings which can regex or non-regex". If you want to see if a string contains a `=` not followed by ~ and not preceeded by ! you can use a regexp or just code that out (which probably is much simpler). – Volker May 25 '21 at 09:31

1 Answers1

2

From regex101:

\b matches, without consuming any characters, immediately between a character matched by \w (a-z) and a character not matched by \w (in either order).
It cannot be used to separate non words from words.

So using \b would not work. (irrespective of the fact regexp might not be the best fit for this case)

To simply test if the string includes =~ (as in "How to check if a string contains a substring in Go")

fmt.Println(strings.Contains(filter, "=~")) // true

See this playground example.

package main

import (
    "fmt"
    "strings"
)

func main() {
    var sep = "=~"
    var filter = "exported_pod=~.*grafana.*"
    matched := strings.Contains(filter, sep)
    fmt.Println(matched)
}

If you need to test for more than one separator though, then yes, regex can help: playground example, with regex tested here.

package main

import "fmt"
import "regexp"

func main() {
    var filter = "exported_pod=~.*grafana.*"
    matched, _ := regexp.MatchString(`[^=!~](=|=~|!=|!~)[^=!~]`, filter)
    fmt.Println(matched)
}

Using a regexp with a named capture group:

[^=!~](?P<separator>=|=~|!=|!~)[^=!~]
       ^^^^^^^^^^^^^

You can extract that separator, using regexp.SubexpIndex (Go 1.15+, Aug. 2020), and use it to split your original string.
See this playground example:

package main

import "fmt"
import "regexp"
import "strings"

func main() {
    var filter = "exported_pod=~.*grafana.*"
    re := regexp.MustCompile(`[^=!~](?P<separator>=|=~|!=|!~)[^=!~]`)
    matches := re.FindStringSubmatch(filter)
    separator := matches[re.SubexpIndex("separator")]
    filtered := strings.Split(filter, separator)
    fmt.Println(filtered)
}

filtered is an array with parts before and after any =~ (the separator detected by the regexp).

VonC
  • 1,262,500
  • 529
  • 4,410
  • 5,250
  • What should be the best way to test for =, =~, !=, !~ in the strings which can regex or non-regex? – zubug55 May 25 '21 at 08:14
  • @zubug55 I have edited the answer to include an example of an alternative approach. – VonC May 25 '21 at 13:47
  • I need to exact match for =, =~, !=, !~ . The problem with your approach is that "exported_pod=~.*grafana.*" will match for = as well. It should only match with =~ – zubug55 May 25 '21 at 18:13
  • @zubug55 It does not match =: https://play.golang.org/p/3eziI5feXuV – VonC May 25 '21 at 19:42
  • package main import ( "fmt" "strings" ) func main() { var sep = "=" var filter = "exported_pod=~.*grafana.*" matched := strings.Contains(filter, sep) fmt.Println(matched) } This will return true. – zubug55 May 25 '21 at 19:58
  • @zubug55 I don't see any mention of =, =~, !=, !~ in your question, only =~ as a separator, with the question "why \b fails when string includes .*". I have answered that question. – VonC May 25 '21 at 20:02
  • @zubug55 I have edited the answer to use a regex which will match only =, =~, !=, !~ – VonC May 25 '21 at 20:09
  • What can be the best way to split the key values after matching with the regex [^=!~](=|=~|!=|!~)[^=!~] – zubug55 May 25 '21 at 20:44
  • 1
    Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/232884/discussion-between-vonc-and-zubug55). – VonC May 25 '21 at 21:26