As a personal project, trying to learn Go(lang) by applying it to something, I am writing an EMCAScript/JavaScript "compiler"; all it will (initially) do is allow you to include other .js files.
Functionality aside, I am pulling my hair out trying to figure out the regexp package. Here is the snippet that does not seem to be doing what I want it to:
// Note: "lines" is an array of strings.
var includeRegex, _ = regexp.Compile("^[ \t]*include[(]{1}\"([^\"]+)\"[)]{1};")
for _, line := range lines {
var isInclude = includeRegex.Match([]byte(line))
if isInclude {
var includeFile = includeRegex.FindString(line)
fmt.Println("INCLUDE", includeFile)
} else {
// ...
}
I have already stumbled across Go's subset of regular expressions, hence why the regex does not read as ^\s*include\("([^"]+)"\);. I have already tested both the preferred, and the Go-style regex, in RegexPal, and both definitely work. The match just never seems to occurr; what am I doing wrong?
For what it's worth, the include() statement I am trying to parse looks like so:
include("somefile.js");
EDIT: For what it's worth, I am keeping the code here.
This seems to work with the latest weekly
package main
import (
"fmt"
"log"
"regexp"
"strings"
)
func main() {
includeRegex, err := regexp.Compile(`^\s*include\("(\\\"|[^"])+"\);`)
if err != nil {
log.Fatal(err)
}
for _, line := range strings.Split(`
foo
include "abc.def"
include("file.js");
include "me\"to\""
include("please\"!\"");
nothing here
`, "\n") {
if includeRegex.Match([]byte(line)) {
includeFile := includeRegex.FindString(line)
fmt.Println("INCLUDE", includeFile)
} else {
fmt.Printf("no match for \"%s\"\n", line)
}
}
}
Output:
$ go build && ./tmp
no match for ""
no match for "foo"
no match for "include "abc.def""
INCLUDE include("file.js");
no match for " include "me\"to\"""
INCLUDE include("please\"!\"");
no match for " nothing here "
no match for ""
$
Try putting the following line at the start of your program:
println(runtime.Version())
It should print weekly.2012-03-13 or something close to that date.
Related
I have a regex like this
REGEX_2_SAME_CHARACTER_IN_A_ROW = "^(?:(.)(?!\\1\\1))*$"
and check password with that regex if it contain 2 same character in a row
contain2SameCharacterInARow, err := regexp.MatchString(REGEX_2_SAME_CHARACTER_IN_A_ROW, password)
but I get this error
error match regex 2 same char in a row: error parsing regexp: invalid or unsupported Perl syntax: `(?!`
I have read other question that using regexp.MustCompile but I don't know how to handle or code it, is there anyone can help me with the solution?
Here you can check my full code for validate password
https://play.golang.com/p/5Fj4-UPvL8s
You don't need the anchor, the non-capturing group, nor the negative lookahead. Simply match and capture any character ((.)) followed by itself (\\1).
REGEX_2_SAME_CHARACTER_IN_A_ROW = "(.)\\1"
But this brings us to the next problem: Go regexes do not support back references, so you need to find a different solution. One would be looping the string yourself.
Here's a solution with a simple loop:
package main
import (
"errors"
"fmt"
"strings"
)
func main() {
fmt.Println(ValidatePassword("passsword01"))
}
func ContainsRepeatedChar(s string) bool {
chars := strings.Split(s, "")
char := chars[0]
for i := 1; i < len(chars); i++ {
if (chars[i] == char) {
return true
}
char = chars[i]
}
return false
}
func ValidatePassword(password string) error {
contain2SameCharacterInARow := ContainsRepeatedChar(password)
if contain2SameCharacterInARow {
fmt.Println("duplicated char")
return errors.New("invalid password")
}
fmt.Println("all good")
return nil
}
I am having some trouble when using github.com/go-validator/validator to validate regex some phone numbers with this prefix +62, 62, 0, for instance number e.g. +628112blabla, 0822blablabla, 628796blablabla.
I have try my regex on online regex tester and no issue with the regex on that. Here the regex is :
(0|\+62|062|62)[0-9]+$
But when I try with my go implement with it, the regex not working. This is my code for implement the purpose :
type ParamRequest struct {
PhoneNumber string `validate:"nonzero,regexp=(0|\+62|062|62)[0-9]+$"`
ItemCode string `validate:"nonzero"`
CallbackUrl string `validate:"nonzero"`
}
func (c *TopupAlloperatorApiController) Post() {
var v models.TopupAlloperatorApi
interf := make(map[string]interface{})
json.Unmarshal(c.Ctx.Input.RequestBody, &interf)
logs.Debug(" Json Input Request ", interf)
var phone, item, callback string
if _, a := interf["PhoneNumber"].(string); a {
phone = interf["PhoneNumber"].(string)
}
if _, b := interf["ItemCode"].(string); b {
item = interf["ItemCode"].(string)
}
if _, c := interf["CallbackUrl"].(string); c {
callback = interf["CallbackUrl"].(string)
}
ve := ParamRequest{
PhoneNumber: phone,
ItemCode: item,
CallbackUrl: callback,
}
logs.Debug(" Param Request ", ve)
err := validator.Validate(ve)
if err == nil {
//success
}else{
// not success
}
Many thanks for anything help. Thank you.
Because you are using regexp to check PhoneNumber that won't be matching if the value is empty it is better to remove nonzero from the validation.
I have checked out documentation and haven't found examples where you can use both: nonzero and regexp.
Also you need to make your regex symbol-escaped, otherwise it won't be detected by reflection. It means you should use (0|\\+62|062|62)[0-9]+$ in your code. Here is example where problem is: symbol escaping in struct tags
And also, please try to use this regexp: ^\\+{0,1}0{0,1}62[0-9]+$
I tried something I did in Javascript.
But it says
http://play.golang.org/p/qlWLI03Dnl
package main
import "fmt"
import "regexp"
import "strings"
func swapit(str string) string {
var validID = regexp.MustCompile(`[a-z]|[A-Z]`)
return validID.ReplaceAllString(str, func(${0}, ${1}, ${2}) string {
return (${1}) ? strings.ToUpper(${0}) : strings.ToLower(${0})
})
}
func main() {
fmt.Println(swapit("hello wOrld."))
// HELLO WoRLD.
}
I also tried this removing ? : syntax but still does not work.
http://play.golang.org/p/mD6_78zzo1
Does really go not support this? Do I just give up and just bruteforce each character to change cases?
Thanks a lot
As #James Henstridge already pointed out, there are multiple problems with your code. This answer will not focus on the errors, but rather a different way of solving the problem.
If your aim is to learn about using regexp in Go, this answer of mine is useless.
If your aim is to get learn how to make a function that swaps cases, then I suggest a solution without regexp, utilizing the unicode package instead:
package main
import (
"bytes"
"fmt"
"unicode"
)
func SwapCase(str string) string {
b := new(bytes.Buffer)
for _, r := range str {
if unicode.IsUpper(r) {
b.WriteRune(unicode.ToLower(r))
} else {
b.WriteRune(unicode.ToUpper(r))
}
}
return b.String()
}
func main() {
fmt.Println(SwapCase("Hej värLDen."))
}
Output:
hEJ VÄRldEN.
Playground
This solution will handle all non A-Z characters as well, such as ö-Ö and å-Å.
I want to replace regex-matched strings with new string but still keeping part of the original text.
I want to get
I own_VERB it and also have_VERB it
from
I own it and also have it
how do I do this with one line of code? I tried but can't get further than this. Thanks,
http://play.golang.org/p/SruLyf3VK_
package main
import "fmt"
import "regexp"
func getverb(str string) string {
var validID = regexp.MustCompile(`(own)|(have)`)
return validID. ReplaceAllString(str, "_VERB")
}
func main() {
fmt.Println(getverb("I own it and also have it"))
// how do I keep the original text like
// I own_VERB it and also have_VERB it
}
You don't even need a capture group for this.
package main
import "fmt"
import "regexp"
func getverb(str string) string {
var validID = regexp.MustCompile(`own|have`)
return validID. ReplaceAllString(str, "${0}_VERB")
}
func main() {
fmt.Println(getverb("I own it and also have it"))
// how do I keep the original text like
// I own_VERB it and also have_VERB it
}
${0} contains the string which matched the whole pattern; ${1} will contain the string which matched the first sub-pattern (or capture group) if there is any, and which you can see in Darka's answer.
Seems a bit googling helps:
var validID = regexp.MustCompile(`(own|have)`)
return validID. ReplaceAllString(str, "${1}_VERB")
Inside replacement, $ signs are interpreted as in Expand, so for instance $1 represents the text of the first submatch.
package main
import (
"fmt"
"regexp"
)
func main() {
re := regexp.MustCompile("(own|have)")
fmt.Println(re.ReplaceAllString("I own it and also have it", "${1}_VERB"))
}
Output
I own_VERB it and also have_VERB it
I want to replace any non-alphanumeric character sequences with a dash. A snippet of what I wrote is below. However it does not work and I'm completely clueless why. Could anyone explain me why the snippet behaves not like I expect it to and what would be the correct way to accomplish this?
package main
import (
"fmt"
"regexp"
"strings"
)
func main() {
reg, _ := regexp.Compile("/[^A-Za-z0-9]+/")
safe := reg.ReplaceAllString("a*-+fe5v9034,j*.AE6", "-")
safe = strings.ToLower(strings.Trim(safe, "-"))
fmt.Println(safe) // Output: a*-+fe5v9034,j*.ae6
}
The forward slashes are not matched by your string.
package main
import (
"fmt"
"log"
"regexp"
"strings"
)
func main() {
reg, err := regexp.Compile("[^A-Za-z0-9]+")
if err != nil {
log.Fatal(err)
}
safe := reg.ReplaceAllString("a*-+fe5v9034,j*.AE6", "-")
safe = strings.ToLower(strings.Trim(safe, "-"))
fmt.Println(safe) // Output: a*-+fe5v9034,j*.ae6
}
(Also here)
Output
a-fe5v9034-j-ae6