What is the difference between regexp.Compile and regexp.CompilePOSIX?

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

What is the difference between regexp.Compile and regexp.CompilePOSIX?

问题

regexp.Compileregexp.CompilePOSIX是Go语言中正则表达式包(regexp)中的两个函数,它们之间有一些区别。

regexp.Compile函数用于编译正则表达式,并返回一个*regexp.Regexp类型的值,该值可以用于匹配和操作字符串。这个函数使用的是Perl语法的正则表达式,支持更多的功能和选项。它是默认的正则表达式编译函数。

regexp.CompilePOSIX函数也用于编译正则表达式,但它使用的是POSIX语法的正则表达式。POSIX语法相对较简单,功能较少,但在某些情况下可能更高效。这个函数返回的也是一个*regexp.Regexp类型的值。

简而言之,regexp.Compile适用于大多数情况,它提供了更多的功能和选项。而regexp.CompilePOSIX适用于那些只需要基本功能且对性能要求较高的情况。

你可以通过以下链接查看更多关于这两个函数的详细信息:

regexp.Compile文档

regexp.CompilePOSIX文档

英文:

Can anyone provide some examples to explain the differences between regexp.Compile and regexp.CompilePOSIX? I read the documentation. But I can't get an intuitive understanding.

答案1

得分: 6

Perl和POSIX兼容的正则表达式在很大程度上相似,但在一些关键方面有所不同,比如子匹配。这在这里有提到:

> POSIX定义了解析子匹配的规则,首先选择字符串中最左边的匹配项。(这是传统的Perl行为,但在这里有所不同。)在字符串最左边的位置开始的子匹配项中,选择最长的子匹配项。

假设你有一个正则表达式(foo|foobar)。当对一个字符串进行匹配时,该字符串可能匹配多个子表达式(例如,foobarbaz可以同时匹配foofoobar),Perl兼容的正则表达式会返回第一个匹配项foo),而POSIX兼容的正则表达式会返回最长的匹配项foobar)。

以下是一些示例代码(playground):

package main

import "fmt"
import "regexp"

func main() {
    pattern := "(foo|foobar)"
    str := []byte("foobarbaz")

	rPCRE, _ := regexp.Compile(pattern)
	rPOSIX, _ := regexp.CompilePOSIX(pattern)
	
	matchesPCRE := rPCRE.Find(str)
	fmt.Println(string(matchesPCRE))
    // 输出 "foo"
	
	matchesPOSIX := rPOSIX.Find(str)
	fmt.Println(string(matchesPOSIX))
    // 输出 "foobar"
}
英文:

Perl- and POSIX-compatible regular expressions are similar in large parts, but differ in some key aspects, like for example submatching. This is mentioned here:

>POSIX defines that to resolve submatches, first chose the match that starts leftmost in the string. (This is traditional Perl behavior but here things diverge.) Among the submatches starting at the leftmost position in the string, choose the longest one overall.

Say you have a regular expression (foo|foobar). When matching this expression against a string that would match several of the subexpressions (for example, foobarbaz would match both subpatterns, foo and foobar), a Perl-compatible regex would return the first match (foo), while a POSIX-compatible regex would return the longest match (foobar).

Some example code (playground):

package main

import "fmt"
import "regexp"

func main() {
    pattern := "(foo|foobar)"
    str := []byte("foobarbaz")

	rPCRE, _ := regexp.Compile(pattern)
	rPOSIX, _ := regexp.CompilePOSIX(pattern)
	
	matchesPCRE := rPCRE.Find(str)
	fmt.Println(string(matchesPCRE))
    // prints "foo"
	
	matchesPOSIX := rPOSIX.Find(str)
	fmt.Println(string(matchesPOSIX))
    // prints "foobar"
}

huangapple
  • 本文由 发表于 2016年1月16日 23:01:15
  • 转载请务必保留本文链接:https://go.coder-hub.com/34828408.html
匿名

发表评论

匿名网友

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

确定