查找、解析和验证电子邮件地址

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

finding, parsing and validating email addresses

问题

import "fmt"

func main() {
    email := "learning@gmail.com"
    atTrue := false
    s := ""
    domain := ""
    tld := ""
    for i := 0; i < len(email); i++ {
        if atTrue {
            s += string(email[i])
        }
        if string(email[i]) == "@" {
            atTrue = true
        }
        if string(email[i]) == "." {
            atTrue = false
            domain = s
            s = ""
        }
    }
    tld = s
    fmt.Println("Domain:", domain, "and TLD:", tld)
}

当前输出:Domain: gmail and TLD: com

期望输出:Domain: gmail and TLD: com

如何指示从某个字符串到某个字符串的循环?

英文:
 import &quot;fmt&quot;

func main() {
    email := &quot;learning@gmail.com&quot;
    atTrue := false
    s := &quot;&quot;
    for i := 0; i &lt; len(email); i++ {
        if atTrue {
            s += string(email[i])
        }
        if string(email[i]) == &quot;@&quot; {
            atTrue = true
        }
    }
    fmt.Println(s)
}

current output: gmail.com

expect output: Domain: gmail and TLD: com

How to indicate looping from certain string to certain string?

答案1

得分: 3

使用strings.Split函数

	email := "learning@gmail.com"
	split := strings.Split(email, "@")
	split = strings.Split(split[1], ".")
	fmt.Println("Domain:", split[0])
	fmt.Println("TLD:", split[1])

你可以使用mail.ParseAddress函数验证电子邮件字符串

	email := "learning@gmail.com"
	addr, err := mail.ParseAddress(email)
	if err != nil {
		log.Fatal(err)
	}

如果TLD是co.id,输出仍然是co.id吗?
尝试找到.的第一个索引(strings.Index),并使用它来分隔字符串

	email := "learning@gmail.co.id"
	split := strings.Split(email, "@")
	index := strings.Index(split[1], ".")
	fmt.Println("Domain:", split[1][:index])
	fmt.Println("TLD:", split[1][index+1:])

或者使用regexp.Split函数

	email := "learning@gmail.co.id"
	split := strings.Split(email, "@")
	split = regexp.MustCompile("[.]").
		Split(split[1], 2)
	fmt.Println("Domain:", split[0])
	fmt.Println("TLD:", split[1])

或者使用strings.SplitN

    email := "learning@gmail.co.id"
	split := strings.Split(email, "@")
	split = strings.SplitN(split[1], ".", 2)
	fmt.Println("Domain:", split[0])
	fmt.Println("TLD:", split[1])

或者使用strings.Cut

	_, host, found := strings.Cut(email, "@")
	if !found {
		t.Fatal("fail cut to host (Domain + TLD)")
	}
	domain, tld, found := strings.Cut(host, ".")
	if !found {
		t.Fatal("fail cut to Domain and TLD")
	}
	fmt.Println("Domain:", domain)
	fmt.Println("TLD:", tld)

PLAYGROUND

基准测试

	const (
		quantity   = 10000
		userLength = 10
		domain     = "gmail.com"
	)
	var (
		letterRunes = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
		emails      = make([]string, 0, quantity)
		seeded      = rand.New(rand.NewSource(time.Now().UnixMilli()))
	)

	for i := 0; i < quantity; i++ {
		user := make([]rune, userLength)
		for i := range user {
			user[i] = letterRunes[seeded.Intn(len(letterRunes))]
		}
		emails = append(emails, fmt.Sprintf("%s@%s", string(user), domain))
	}

	b.Run("strings.Split", func(b *testing.B) {
		b.ReportAllocs()
		b.ResetTimer()
		var domain, tld string
		for i := 0; i < b.N; i++ {
			for _, email := range emails {
				domain, tld = stringsSplit(email)
			}
		}
		_, _ = domain, tld
	})
	b.Run("strings.SplitN", func(b *testing.B) {
		b.ReportAllocs()
		b.ResetTimer()
		var domain, tld string
		for i := 0; i < b.N; i++ {
			for _, email := range emails {
				domain, tld = stringsSplitN(email)
			}
		}
		_, _ = domain, tld
	})
	b.Run("strings.Index+strings.Split", func(b *testing.B) {
		b.ReportAllocs()
		b.ResetTimer()
		var domain, tld string
		for i := 0; i < b.N; i++ {
			for _, email := range emails {
				domain, tld = stringsIndexAndStringsSplit(email)
			}
		}
		_, _ = domain, tld
	})
	b.Run("regexp.Split", func(b *testing.B) {
		b.ReportAllocs()
		b.ResetTimer()
		var domain, tld string
		for i := 0; i < b.N; i++ {
			for _, email := range emails {
				domain, tld = regexpSplit(email)
			}
		}
		_, _ = domain, tld
	})
	b.Run("strings.Cut", func(b *testing.B) {
		b.ReportAllocs()
		b.ResetTimer()
		var domain, tld string
		for i := 0; i < b.N; i++ {
			for _, email := range emails {
				domain, tld = stringsCut(email)
			}
		}
		_, _ = domain, tld
	})
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Benchmark
Benchmark/strings.Split
Benchmark/strings.Split-12         	        752	   1563851 ns/op	  640002 B/op	   20000 allocs/op
Benchmark/strings.SplitN
Benchmark/strings.SplitN-12        	        805	   1463329 ns/op	  640003 B/op	   20000 allocs/op
Benchmark/strings.Index+strings.Split
Benchmark/strings.Index+strings.Split-12   1416	    858783 ns/op	  320000 B/op	   10000 allocs/op
Benchmark/regexp.Split
Benchmark/regexp.Split-12                    85	  14605240 ns/op	11088513 B/op	  160024 allocs/op
Benchmark/strings.Cut
Benchmark/strings.Cut-12                   6597	    180579 ns/op	       0 B/op	       0 allocs/op
PASS
英文:

Use strings.Split function

	email := &quot;learning@gmail.com&quot;
split := strings.Split(email, &quot;@&quot;)
split = strings.Split(split[1], &quot;.&quot;)
fmt.Println(&quot;Domain:&quot;, split[0])
fmt.Println(&quot;TLD:&quot;, split[1])

optionally you can validate an email string with mail.ParseAddress function

	email := &quot;learning@gmail.com&quot;
addr, err := mail.ParseAddress(email)
if err != nil {
log.Fatal(err)
}

> what if the TLD goes like this co.id, does the output still co.id ? –
@zacharyy

simply try to find the first index of . (strings.Index) and use one to separate the string

	email := &quot;learning@gmail.co.id&quot;
split := strings.Split(email, &quot;@&quot;)
index := strings.Index(split[1], &quot;.&quot;)
fmt.Println(&quot;Domain:&quot;, split[1][:index])
fmt.Println(&quot;TLD:&quot;, split[1][index+1:])

or use regexp.Split function

	email := &quot;learning@gmail.co.id&quot;
split := strings.Split(email, &quot;@&quot;)
split = regexp.MustCompile(&quot;[.]&quot;).
Split(split[1], 2)
fmt.Println(&quot;Domain:&quot;, split[0])
fmt.Println(&quot;TLD:&quot;, split[1])

or strings.SplitN

    email := &quot;learning@gmail.co.id&quot;
split := strings.Split(email, &quot;@&quot;)
split = strings.SplitN(split[1], &quot;.&quot;, 2)
fmt.Println(&quot;Domain:&quot;, split[0])
fmt.Println(&quot;TLD:&quot;, split[1])

or strings.Cut

	_, host, found := strings.Cut(email, &quot;@&quot;)
if !found {
t.Fatal(&quot;fail cut to host (Domain + TLD)&quot;)
}
domain, tld, found := strings.Cut(host, &quot;.&quot;)
if !found {
t.Fatal(&quot;fail cut to Domain and TLD&quot;)
}
fmt.Println(&quot;Domain:&quot;, domain)
fmt.Println(&quot;TLD:&quot;, tld)

👉🏻 <kbd>PLAYGROUND</kbd> 👈🏻

Benchmarks

	const (
quantity   = 10000
userLength = 10
domain     = &quot;gmail.com&quot;
)
var (
letterRunes = []rune(&quot;abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ&quot;)
emails      = make([]string, 0, quantity)
seeded      = rand.New(rand.NewSource(time.Now().UnixMilli()))
)
for i := 0; i &lt; quantity; i++ {
user := make([]rune, userLength)
for i := range user {
user[i] = letterRunes[seeded.Intn(len(letterRunes))]
}
emails = append(emails, fmt.Sprintf(&quot;%s@%s&quot;, string(user), domain))
}
b.Run(&quot;strings.Split&quot;, func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
var domain, tld string
for i := 0; i &lt; b.N; i++ {
for _, email := range emails {
domain, tld = stringsSplit(email)
}
}
_, _ = domain, tld
})
b.Run(&quot;strings.SplitN&quot;, func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
var domain, tld string
for i := 0; i &lt; b.N; i++ {
for _, email := range emails {
domain, tld = stringsSplitN(email)
}
}
_, _ = domain, tld
})
b.Run(&quot;strings.Index+strings.Split&quot;, func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
var domain, tld string
for i := 0; i &lt; b.N; i++ {
for _, email := range emails {
domain, tld = stringsIndexAndStringsSplit(email)
}
}
_, _ = domain, tld
})
b.Run(&quot;regexp.Split&quot;, func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
var domain, tld string
for i := 0; i &lt; b.N; i++ {
for _, email := range emails {
domain, tld = regexpSplit(email)
}
}
_, _ = domain, tld
})
b.Run(&quot;strings.Cut&quot;, func(b *testing.B) {
b.ReportAllocs()
b.ResetTimer()
var domain, tld string
for i := 0; i &lt; b.N; i++ {
for _, email := range emails {
domain, tld = stringsCut(email)
}
}
_, _ = domain, tld
})
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
Benchmark
Benchmark/strings.Split
Benchmark/strings.Split-12         	        752	   1563851 ns/op	  640002 B/op	   20000 allocs/op
Benchmark/strings.SplitN
Benchmark/strings.SplitN-12        	        805	   1463329 ns/op	  640003 B/op	   20000 allocs/op
Benchmark/strings.Index+strings.Split
Benchmark/strings.Index+strings.Split-12   1416	    858783 ns/op	  320000 B/op	   10000 allocs/op
Benchmark/regexp.Split
Benchmark/regexp.Split-12                    85	  14605240 ns/op	11088513 B/op	  160024 allocs/op
Benchmark/strings.Cut
Benchmark/strings.Cut-12                   6597	    180579 ns/op	       0 B/op	       0 allocs/op
PASS

huangapple
  • 本文由 发表于 2022年11月1日 19:06:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/74274942.html
匿名

发表评论

匿名网友

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

确定