How do I check a string for one or more symbols

时间:2019-01-15 18:10:30

标签: string go

I'm struggling to find a method of checking to see if a string contains one or more symbols like the following: #}{&*"(£) While it's fairly trivial to make a check for one or more of these symbols I'm not looking to build and maintain a list or dictionary of possible entries. Is there a way I can check to see if a string contains one or more of any non standard symbol in go preferably using the standard library?

Specifically I'm looking to detect anything that isn't a-zA-Z0-9 which for the basis of my question would be counted as a non standard symbol.

2 个答案:

答案 0 :(得分:6)

在Go中,编写一个简单的函数。例如,

package main

import (
    "fmt"
)

func isStandard(s string) bool {
    for i := 0; i < len(s); i++ {
        switch b := s[i]; {
        case b >= 'a' && b <= 'z':
            continue
        case b >= 'A' && b <= 'Z':
            continue
        case b >= '0' && b <= '9':
            continue
        default:
            return false
        }
    }
    return true
}

func main() {
    fmt.Println(isStandard(`ABCabc123`))
    fmt.Println(isStandard(`#}{&*"(£)`))
}

游乐场:https://play.golang.org/p/Y2KjDcHSupH

输出:

true
false

  

The Go Programming Language Specification

     

Switch statements

     

“ Switch”语句提供多路执行。表达式或类型   将说明符与“开关”内的“案例”进行比较以确定   要执行哪个分支。

     

表达开关

     

在表达式开关中,对开关表达式求值,并且   对不需要为常量的case表达式进行求值   从左到右和从上到下;第一个等于开关   表达式触发相关语句的执行   案件;其他情况将被跳过。如果没有大小写匹配并且有一个   在“默认”情况下,将执行其语句。最多可以有一个   默认情况下,它可能会出现在“ switch”语句中的任何地方。

     

switch表达式前面可能有一个简单的语句,该语句   在对表达式求值之前执行。

     

Fallthrough statements

     

“ fallthrough”语句将控制权转移到   表达式“ switch”语句中的下一个case子句。可能是   只能用作此类子句中的最终非空语句。


switch b := s[i]; {
    // ...
}

等效于

switch b := s[i]; true {
    // ...
}

等同于

{
    b := s[i]
    switch true {
        // ...
    } 
}

简单的语句b := s[i]声明bswitch { }语句块局部变量。

评估案例表达式并将其与true进行比较。如果都不为真,则使用default

与C不同,Go需要显式fallthrough

ASCII是Unicode UTF-8的子集。由于标准字符都是ASCII,因此我们可以简单地比较字节。


这是一个简单的基准。

输出:

$ go test standard_test.go -bench=. -benchmem
BenchmarkPeterSO-8    200000000       8.10 ns/op    0 B/op    0 allocs/op
BenchmarkJubobs-8      10000000     222 ns/op       0 B/op    0 allocs/op
$ 

standard_test.go

package main

import (
    "regexp"
    "testing"
)

func isStandard(s string) bool {
    for i := 0; i < len(s); i++ {
        switch b := s[i]; {
        case b >= 'a' && b <= 'z':
            continue
        case b >= 'A' && b <= 'Z':
            continue
        case b >= '0' && b <= '9':
            continue
        default:
            return false
        }
    }
    return true
}

func BenchmarkPeterSO(b *testing.B) {
    std := `ABCabc123`
    for N := 0; N < b.N; N++ {
        isStandard(std)
    }
}

var (
    whitelist  = "A-Za-z0-9"
    disallowed = regexp.MustCompile("[^" + whitelist + " ]+")
)

func IsValid(s string) bool {
    return !disallowed.MatchString(s)
}

func BenchmarkJubobs(b *testing.B) {
    std := `ABCabc123`
    for N := 0; N < b.N; N++ {
        IsValid(std)
    }
}

答案 1 :(得分:3)

由于可以轻松地将白名单定义为正则表达式,因此请使用regexp.MatchString

package main

import (
    "fmt"
    "regexp"
)

var (
    whitelist  = "A-Za-z0-9"
    disallowed = regexp.MustCompile(fmt.Sprintf("[^%s]+", whitelist))
)

func main() {
    fmt.Println(IsValid("foobar007"))
    fmt.Println(IsValid("foo%bar&007"))
}

func IsValid(s string) bool {
    return !disallowed.MatchString(s)
}

playground