Joshua LI
Joshua LI

Reputation: 4733

How to check if a string only contains alphabetic characters in Go?

I am trying to check the username whether is only containing alphabetic characters. What is the idiomatic way to check it in Go?

Upvotes: 59

Views: 99943

Answers (6)

user6169399
user6169399

Reputation:

you may use unicode.IsLetter like this working sample code:

package main

import "fmt"
import "unicode"

func IsLetter(s string) bool {
    for _, r := range s {
        if !unicode.IsLetter(r) {
            return false
        }
    }
    return true
}

func main() {
    fmt.Println(IsLetter("Alex")) // true
    fmt.Println(IsLetter("123"))  // false
}

or since go1.21:

package main

import (
    "fmt"
    "strings"
    "unicode"
)

func IsLetter(s string) bool {
    return !strings.ContainsFunc(s, func(r rune) bool {
        return !unicode.IsLetter(r)
    })
}

func main() {
    fmt.Println(IsLetter("Alex"))  // true
    fmt.Println(IsLetter("123 a")) // false

}

or if you have limited range e.g. 'a'..'z' and 'A'..'Z', you may use this working sample code:

package main

import "fmt"

func IsLetter(s string) bool {
    for _, r := range s {
        if (r < 'a' || r > 'z') && (r < 'A' || r > 'Z') {
            return false
        }
    }
    return true
}
func main() {
    fmt.Println(IsLetter("Alex"))  // true
    fmt.Println(IsLetter("123 a")) // false

}

or since go1.21:

package main

import (
    "fmt"
    "strings"
    "unicode"
)

func IsLetter(s string) bool {
    return !strings.ContainsFunc(s, func(r rune) bool {
        return (r < 'a' || r > 'z') && (r < 'A' || r > 'Z')
    })
}

func main() {
    fmt.Println(IsLetter("Alex"))  // true
    fmt.Println(IsLetter("123 a")) // false

}

or if you have limited range e.g. 'a'..'z' and 'A'..'Z', you may use this working sample code:

package main

import "fmt"
import "regexp"

var IsLetter = regexp.MustCompile(`^[a-zA-Z]+$`).MatchString

func main() {
    fmt.Println(IsLetter("Alex")) // true
    fmt.Println(IsLetter("u123")) // false
}

Upvotes: 116

Amirhossein Shamsi
Amirhossein Shamsi

Reputation: 1

package main

import (
    "fmt"
    "strings"
    "unicode"
)

func isLetter(c rune) bool {
    return !unicode.IsLetter(c)
}
func main() {
    fmt.Printf(" desired word : %s\n", strings.TrimFunc("12333", isLetter)) //ignored it
    fmt.Printf(" desired word : %s\n", strings.TrimFunc("abcd", isLetter))  //take  it

}

Upvotes: 0

Feckmore
Feckmore

Reputation: 4714

One approach is to use FieldsFunc from Go's strings library.

The following compares each character in the username with the set of unicode letters. Similar to the strings.Split function, FieldsFunc splits the username into a slice along boundaries of non-matching characters (in this case, unicode letters). Below, we compare the original username with the joined elements of the slice.

func lettersOnly(username string) bool {
    nonLetter := func(c rune) bool { return !unicode.IsLetter(c) }
    words := strings.FieldsFunc(username, nonLetter)
    return username == strings.Join(words, "")
}

Playground Example: https://play.golang.org/p/4aWKCu9upox

We can also compare the username against a list of very specific characters, combining strings.FieldsFunc with strings.ContainsAny.

func hawaiianOnly(username string) bool {
    hawaiian := `aeiouhklmnpwʻ`
    nonCharacter := func(c rune) bool { return !strings.ContainsAny(hawaiian, strings.ToLower(string(c))) }
    words := strings.FieldsFunc(username, nonCharacter)
    return username == strings.Join(words, "")
}

Playground Example:https://play.golang.org/p/ipwAOC3c72P

Upvotes: 1

stwykd
stwykd

Reputation: 2884

You can also do this concisely without importing any packages

func isLetter(c rune) bool {
    return ('a' <= c && c <= 'z') || ('A' <= c && c <= 'Z')
}

func isWord(s string) bool {
    for _, c := range s {
        if !isLetter(c) {
            return false
        }
    }
    return true
}

Upvotes: 6

Mr_Pink
Mr_Pink

Reputation: 109347

Assuming you're only looking for ascii letters, you would normally see this implemented as a regular expression using the alpha character class [[:alpha:]] or the equivalent [A-Za-z]

isAlpha := regexp.MustCompile(`^[A-Za-z]+$`).MatchString

for _, username := range []string{"userone", "user2", "user-three"} {
    if !isAlpha(username) {
        fmt.Printf("%q is not valid\n", username)
    }
}

https://play.golang.org/p/lT9Fki7tt7

Upvotes: 13

Tom Cleveland
Tom Cleveland

Reputation: 379

Here's the way I'd do it:

import "strings"

const alpha = "abcdefghijklmnopqrstuvwxyz"

func alphaOnly(s string) bool {
   for _, char := range s {  
      if !strings.Contains(alpha, strings.ToLower(string(char))) {
         return false
      }
   }
   return true
}

Upvotes: 10

Related Questions