在Golang中的正则表达式问题

huangapple go评论72阅读模式
英文:

Issue with regex in Golang

问题

我正在尝试创建一个正则表达式来解析特定的字符串。

当前的字符串是abcd_1.263.0.15-8zz00df.yml,我想要解析出其中的1.263.0.15-8zz00df

已经尝试使用这个表达式"_\K.*(?=\.)",但在Golan中不起作用,并给出了模式错误。有人可以帮忙吗?

英文:

I am trying to create a regex to parse specific string .

The current string is abcd_1.263.0.15-8zz00df.yml and I want to parse only 1.263.0.15-8zz00df out of it.

Tried already with this expression "_\K.*(?=\.)" but its not working in Golan and giving me pattern error. Can someone please help with this?

答案1

得分: 2

Go 使用的是 RE2 正则表达式引擎,该引擎不支持 lookaheadslookbehinds 和其他 PCRE 的特性,比如 \K

可以参考这个比较不同的正则表达式引擎。

不过,你可以使用以下正则表达式:

[^_-]+-[^.]+

可以参考这个演示

解释:

[^_-]+   # 一个不是“_”或“-”的字符,出现一次或多次
-        # 一个字面上的“-”
[^.]+    # 一个不是点号的字符,出现一次或多次
英文:

Go uses RE2 regex engine, that does not support lookaheads, lookbehinds and other PCRE goodies like \K

See this comparison of the different regex engines.

You could however use this regex:

[^_-]+-[^.]+

See this demo.

Explained:

[^_-]+   # a character that is not "_" or "-", one or more times
-        # a literal "-"
[^.]+    # a character that is not a dot, one or more times

答案2

得分: 1

只是转发了@mkopriva的一个代码片段,并附上一句话,不是所有的事情都需要使用正则表达式:

s := "abcd_1.263.0.15-8zz00df.yml"

if i := strings.IndexByte(s, '_'); i > -1 {
    s = s[i+1:]
}
if i := strings.LastIndexByte(s, '.'); i > -1 {
    s = s[:i]
}

fmt.Println(s)

playground

英文:

Just reposting one of @mkopriva's snippets with a sentence,

not everything needs to be done with regular expressions :

	s := "abcd_1.263.0.15-8zz00df.yml"

	if i := strings.IndexByte(s, '_'); i > -1 {
		s = s[i+1:]
	}
	if i := strings.LastIndexByte(s, '.'); i > -1 {
		s = s[:i]
	}

	fmt.Println(s)

playground

答案3

得分: 0

你可以简单地使用正则表达式:

_(.*)\.

* 是贪婪匹配符号,意味着它会匹配到最后一个 '.' 之前的所有内容 - 这正是你所需要的。你的匹配结果在第一组中。


为什么你要使用 \K 匹配器?你的正则表达式可以这样工作:

_(.*)(?=\.)

第一组中包含了你的匹配结果。

注意:一个非常有用的测试正则表达式的工具是这个网站:https://regexr.com/

英文:

Edit: You can simply use the regular expression:

_(.*)\.

The * matches greedily, which means that it will match everything until the last '.' - this is exactly what you need. Your match is in group 1.


Why are you using the \K matcher? Your regular expression works like this:

_(.*)(?=\.)

and group 1 contains your match.

Note: a very helpful tool to test regular expressions is this site: https://regexr.com/

答案4

得分: 0

对于更精确匹配该字符串格式,您可以使用捕获组,并且由于字符串中似乎没有空格,您可以使用\S代替.

_(\S+)\.yml$
  • _ 匹配前导下划线
  • (\S+) 在第一组中捕获1个或多个非空白字符
  • \.yml 匹配 .yml
  • $ 字符串结束

请参见正则表达式演示

例如

package main
import (
    "fmt"
    "regexp"
)

func main(){
    re := regexp.MustCompile(`_(\S+)\.yml$`)
    res := re.FindStringSubmatch("abcd_1.263.0.15-8zz00df.yml")
    fmt.Printf("%v", res[1])
}

输出

1.263.0.15-8zz00df

或者更广泛的匹配,捕获到最后一个点之前的内容:

_(\S+)\.

请参见另一个正则表达式演示

英文:

For a bit more precise match for that string format, you can use a capture group, and as there do not seem to be spaces in the string you can use \S instead of .

_(\S+)\.yml$
  • _ Match the leading underscore
  • (\S+) Capture 1+ non whitespace chars in group 1
  • \.yml Match .yml
  • $ End of string

See a regex demo.

For example

package main
import (
    "fmt"
    "regexp"
)

func main(){
	re := regexp.MustCompile(`_(\S+)\.yml$`)
	res := re.FindStringSubmatch("abcd_1.263.0.15-8zz00df.yml")
	fmt.Printf("%v", res[1])
}

Output

1.263.0.15-8zz00df

<hr>

Or a broader match, capturing till before the last occurrence of the dot:

_(\S+)\.

See another regex demo.

huangapple
  • 本文由 发表于 2022年1月7日 14:55:24
  • 转载请务必保留本文链接:https://go.coder-hub.com/70617588.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定