go语言内置的regexp包实现了正则表达式搜索。通过这个包提供的方法,我们可以使用正则表达式判断一个IPv4地址是否合法。具体代码如下所示:

    1. package main
    2. import "regexp"
    3. import "fmt"
    4. func main() {
    5. str := "1.2.3.4"
    6. ipReg := `^((0|[1-9]\d?|1\d\d|2[0-4]\d|25[0-5])\.){3}(0|[1-9]\d?|1\d\d|2[0-4]\d|25[0-5])$`
    7. match, _ := regexp.MatchString(ipReg, str)
    8. if match {
    9. fmt.Printf("%s is a legal ipv4 address\n", str)
    10. } else {
    11. fmt.Printf("%s is not a legal ipv4 address\n", str)
    12. }
    13. }

    对于上面的代码而言,它虽然能实现判断IPv4地址的合法性,但有一个缺点是速度比较慢,我有将近1900万个字符串需要进行判断,用上面的代码来处理这么多字符串,程序的运行时间大概接近500秒,这远远超过匹配后对这些字符串所进行的其他处理操作,因此,在这里需要寻找更快的匹配方法。
    经过查阅资料可知,可以先对正则表达式进行编译,以得到一个优化的Regexp结构体,然后再用优化后的对象进行匹配。具体代码如下所示:

    1. package main
    2. import "regexp"
    3. import "fmt"
    4. func main() {
    5. str := "1.2.3.4"
    6. ipReg := `^((0|[1-9]\d?|1\d\d|2[0-4]\d|25[0-5])\.){3}(0|[1-9]\d?|1\d\d|2[0-4]\d|25[0-5])$`
    7. r, _ := regexp.Compile(ipReg)
    8. match := r.MatchString(str)
    9. if match {
    10. fmt.Printf("%s is a legal ipv4 address\n", str)
    11. } else {
    12. fmt.Printf("%s is not a legal ipv4 address\n", str)
    13. }
    14. }

    除了对正则表达进行编译外,还有另外一个方法可以高效的对IPv4地址的合法性进行判断,那就是使用net包里面的ParseIP方法。具体代码如下所示:

    1. package main
    2. import "net"
    3. import "fmt"
    4. func main() {
    5. str := "1.2.3.4"
    6. address := net.ParseIP(str)
    7. if address != nil {
    8. fmt.Printf("%s is a legal ipv4 address\n", str)
    9. } else {
    10. fmt.Printf("%s is not a legal ipv4 address\n", str)
    11. }
    12. }

    使用100万个字符串对上述三种方法分别进行测试,得到的程序运行时间分别是:

    1. 25745ms, 161ms, 16ms

    从上述结果来看,net包中的ParseIP方法在判断IPv4地址的合法性上具有压倒性的优势。