Golang regex get value inside parentheses - regex

Code:
package main
import (
"fmt"
"regexp"
)
func main() {
r := regexp.MustCompile(`((.*))`)
s := `(tag)SomeText`
res := r.FindStringSubmatch(s)
fmt.Println(res[1])
}
How to Get Value inside parentheses?

1- While it is simple using regex (try it on The Go Playground):
package main
import (
"fmt"
"regexp"
)
var rgx = regexp.MustCompile(`\((.*?)\)`)
func main() {
s := `(tag)SomeText`
rs := rgx.FindStringSubmatch(s)
fmt.Println(rs[1])
}
output:
tag
2- but sometimes using strings.Index is fast enough (try it on The Go Playground):
package main
import (
"fmt"
"strings"
)
func match(s string) string {
i := strings.Index(s, "(")
if i >= 0 {
j := strings.Index(s, ")")
if j >= 0 {
return s[i+1 : j]
}
}
return ""
}
func main() {
s := `Some(tag)Text`
r := match(s)
fmt.Println(r)
}
output:
tag
3- This simple benchmark shows using regex takes 931ms and using strings.Index takes 43ms for 1000000 iterations.
package main
import (
"fmt"
"regexp"
"strings"
"time"
)
var rgx = regexp.MustCompile(`\((.*?)\)`)
const n = 1000000
func main() {
var rs []string
var r string
s := `(tag)SomeText`
t := time.Now()
for i := 0; i < n; i++ {
rs = rgx.FindStringSubmatch(s)
}
fmt.Println(time.Since(t))
fmt.Println(rs[1]) // [(tag) tag]
t = time.Now()
for i := 0; i < n; i++ {
r = match(s)
}
fmt.Println(time.Since(t))
fmt.Println(r)
}
func match(s string) string {
i := strings.Index(s, "(")
if i >= 0 {
j := strings.Index(s, ")")
if j >= 0 {
return s[i+1 : j]
}
}
return ""
}

I got My problem solved by this regex
r := regexp.MustCompile(`\((.*?)\)`)

Refer to answers, I made my version of the code.
link: https://play.golang.org/p/b82iPZGU1gw
package main
import (
"fmt"
"strings"
)
func match(start, end, s string) string {
i := strings.Index(s, start)
if i >= 0 {
j := strings.Index(s[i:], end)
if j >= 0 {
return s[i+len(start) : i+j]
}
}
return ""
}
func main() {
errText := `facebook: Error validating access token: Session has expired on Tuesday, 28-Jul-20 22:00:00 PDT. The current time is Wednesday, 29-Jul-20 17:55:22 PDT. (code: 190; error_subcode: 463, error_user_title: , error_user_msg: )`
start := "code: "
end := ";"
r := match(start, end, errText)
fmt.Println(r)
}

Related

I want to use GoLang's regular expression to perform an ambiguous search for values enclosed in the `*` string

I'm not good at regular expressions.
I want to use fuzzy search to get the value of a key enclosed with * in text.
package main
import (
"fmt"
"log"
"regexp"
)
func main() {
text := "*company* example company!!\n*tel* 09000009999\n*"
regex := fmt.Sprintf(`(?m)\*%s\*\s\s(.+)$`, "company")
rep := regexp.MustCompile(regex)
result := rep.FindAllStringSubmatch(text, -1)
if result != nil {
log.Print(result[0][1])
} else {
log.Print("empty")
}
}
Output results
example company!!
Change the text variable.
package main
import (
"fmt"
"log"
"regexp"
)
func main() {
text := "*company_name* example company!!\n*tel* 09000009999\n*"
regex := fmt.Sprintf(`(?m)\*%s\*\s\s(.+)$`, "company")
rep := regexp.MustCompile(regex)
result := rep.FindAllStringSubmatch(text, -1)
if result != nil {
log.Print(result[0][1])
} else {
log.Print("empty")
}
}
Output results
empty
How do I get company in an ambiguous search?
I want to search for something like "like 'company%'" like in the SQL like clause.
For now, it's done.
package main
import (
"fmt"
"log"
"regexp"
)
func main() {
text := "*1company_name1234* example company!!\n*tel* 09000009999\n*"
regex := fmt.Sprintf(`(?m)\*.*%s.*\*\s\s(.+)$`, "company")
rep := regexp.MustCompile(regex)
result := rep.FindAllStringSubmatch(text, -1)
if result != nil {
log.Print(result[0][1])
} else {
log.Print("empty")
}
}

How to match phrase between words

I am trying to only capture user-context from the code block below. So in a nutshell I want everything between repo_ and _tag Please send examples.
package main
import (
"regexp"
"fmt"
)
func main() {
var re = regexp.MustCompile(`repo_(.*)_tag`)
var str = `#gitflow
variable "repo_user-context_tag" {
default = "blah"
}
#gitflow
variable "repo_user-office_tag" {
default = "blah"
}
`
for _, match := range re.FindAllString(str, -1) {
fmt.Println(match)
}
}
Output:
repo_user-context_tag
repo_user-office_tag
There's nothing wrong with your regexp. The problem is that you're using the wrong function to see the substring match you're looking for.
Instead of FindAllString, you need FindAllStringSubmatch:
package main
import (
"regexp"
"fmt"
)
func main() {
var re = regexp.MustCompile(`repo_(.*)_tag`)
var str = `#gitflow
variable "repo_user-context_tag" {
default = "blah"
}
#gitflow
variable "repo_user-office_tag" {
default = "blah"
}
`
for _, match := range re.FindAllStringSubmatch(str, -1) {
fmt.Println(match[1])
}
}
See it on the playground.
Output:
user-context
user-office

Relationships are always nil when doing dynamoattribute.UnmarshalMap

I have two structs. Sample and Test. 'Sample' has a relationship of type 'Test'. When I try to do 'dynamoattribute.UnmarshalMap', the relationship is always nil. Could you advise how to populate relationships ('Test' in this case) please?
package main
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
)
type Sample struct {
SampleId string `jsonapi:"attr,sampleId,omitempty" dynamodbav:"sample_id"`
Test *Test `jsonapi:"relation,test"`
}
type Test struct {
TestId string `jsonapi:"attr,testId,omitempty" dynamodbav:"test_id"`
}
func main() {
var m map[string]*dynamodb.AttributeValue
m = make(map[string]*dynamodb.AttributeValue)
m["sample_id"] = &dynamodb.AttributeValue{
S: aws.String("sample1"),
}
m["test_id"] = &dynamodb.AttributeValue{
S: aws.String("test"),
}
sam := Sample{}
err := dynamodbattribute.UnmarshalMap(m, &sam)
if err != nil {
fmt.Println(err)
}
fmt.Println(sam)
}
package main
import (
"fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/service/dynamodb"
"github.com/aws/aws-sdk-go/service/dynamodb/dynamodbattribute"
)
type Sample struct {
SampleId string `jsonapi:"attr,sampleId,omitempty" dynamodbav:"sample_id"`
Test *Test `jsonapi:"relation,test"`
}
type Test struct {
TestId string `jsonapi:"primary,testId" dynamodbav:"test_id"`
}
func main() {
var m map[string]*dynamodb.AttributeValue
m = make(map[string]*dynamodb.AttributeValue)
m["sample_id"] = &dynamodb.AttributeValue{
S: aws.String("sample1"),
}
var mTest map[string]*dynamodb.AttributeValue
mTest = make(map[string]*dynamodb.AttributeValue)
mTest["test_id"] = &dynamodb.AttributeValue{
S: aws.String("test1"),
}
m["test"] = &dynamodb.AttributeValue{
M: mTest,
}
sam := Sample{}
err := dynamodbattribute.UnmarshalMap(m, &sam)
if err != nil {
fmt.Println(err)
}
fmt.Println(sam)
}

Gorilla Mux Regex for number between range and predefined options

My route looks like this
max := viper.GetInt("channels")
lights_router.Path("/{channel}/{action}").
Methods("OPTIONS","GET").
Handler( util.Adapt(SerialHandler(router), util.EnableCORS()))
Channels have to be between 1 and max and action has to be either false or true.
func ValidetaChannel() Adapter {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
channel, err := strconv.Atoi(mux.Vars(r)["channel"])
if err != nil {
http.Error(w, http.StatusText(400), 400)
return
}
if channel >= 1 && channel <= viper.GetInt("channels") {
h.ServeHTTP(w, r)
return
}
http.Error(w, http.StatusText(400), 400)
})
}
}
func ValidetaAction() Adapter {
return func(h http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if mux.Vars(r)["action"] == "true" || mux.Vars(r)["action"] == "false" {
h.ServeHTTP(w, r)
return
}
http.Error(w, http.StatusText(400), 400)
})
}
}
filter by Route
"/{channel:(?:[0-9]{1,3})}/{action:(?:true|false)}/"
Example
package main
import (
"github.com/gorilla/mux"
"log"
"net/http"
"regexp"
"strconv"
)
var myRegex *regexp.Regexp
func main() {
mux := mux.NewRouter()
myRegex = regexp.MustCompile(`/(?P<channel>[0-9]{1,3})/(?P<action>(true|false))/`)
maxChannel := 100
mux.Path("/{channel:(?:[0-9]{1,3})}/{action:(?:true|false)}/").
HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
matchs := myRegex.FindStringSubmatch(r.URL.Path) // [all, channel, action]
/* https://stackoverflow.com/a/20751656/9935654
dict := make(map[string]string)
for i, name := range myRegex.SubexpNames() {
if i != 0 && name != "" {
dict[name] = matchs[i]
}
}
channelStr := dict["channel"]
*/
channelStr := matchs[1]
curChannel, _ := strconv.Atoi(channelStr)
if channelStr[:1] == "0" || curChannel > maxChannel {
log.Println("error")
return
}
log.Println("ok")
})
server := http.Server{Addr:":1234", Handler: mux}
server.ListenAndServe()
}

Regex end modifier not returning results in a Go program

I have a simple program in Go to aid in learning regular expressions. It runs in an infinite loop and has 2 channels, one which is used to provide input (input contains regex pattern and subject), and the second one, which provides the output.
usage: main.exe (cat)+ catcatdog
However there is propably something wrong in the code, as i can't seem to get any results with the $ modifier.
For example, i expect "cat" output from
main.exe cat$ cat\ndog
yet receive zero results.
Code:
package main
import (
"fmt"
"regexp"
"bufio"
"os"
"strings"
)
type RegexRequest struct {
regex string
subject string
}
func main() {
regexRequests := make(chan *RegexRequest)
defer close(regexRequests)
regexAnswers, err := createResolver(regexRequests)
defer close(regexAnswers)
if(err != nil) { // TODO: Panics when exited via ctrl+c
panic(err)
}
interact(regexRequests, regexAnswers)
}
func interact(regexRequests chan *RegexRequest, regexAnswers chan []string) {
for {
fmt.Println("Enter regex and subject: ")
reader := bufio.NewReader(os.Stdin)
line, err := reader.ReadString('\n')
if(err != nil) {
panic(err)
}
regAndString := strings.SplitN(line, " ", 2);
if len(regAndString) != 2 {
fmt.Println("Invalid input, expected [regex][space][subject]")
continue
}
regexRequests <- &RegexRequest{ regAndString[0], regAndString[1] }
result := <- regexAnswers
var filteredResult []string
for _, element := range result {
if(element != "") {
filteredResult = append(filteredResult, element)
} else {
filteredResult = append(filteredResult, "EMPTY");
}
}
fmt.Println(strings.Join(filteredResult, " "))
}
}
func createResolver(inputChan chan *RegexRequest)(outputChan chan []string, err error) {
if(cap(inputChan) > 0) {
return nil, fmt.Errorf("Expected an unbuffered channel")
}
outputChan = make(chan []string)
err = nil
go func() {
for {
var regReq *RegexRequest= (<- inputChan);
var regex *regexp.Regexp = regexp.MustCompile(regReq.regex)
outputChan <- regex.FindAllString(regReq.subject, -1)
}
}()
return
}
Check your regex pattern. For example,
Enter regex and subject:
cat$ cat\ndog
Enter regex and subject:
^cat cat\ndog
cat