代码之家  ›  专栏  ›  技术社区  ›  li x

如何检查一个或多个符号的字符串

  •  -1
  • li x  · 技术社区  · 6 年前

    我正在努力寻找一种检查字符串是否包含以下一个或多个符号的方法: #}{&*"(£) 虽然检查这些符号中的一个或多个是相当简单的,但我并不想建立和维护一个可能条目的列表或字典。有没有方法可以检查一个字符串是否包含 任何 Go中的非标准符号最好使用标准库?

    具体地说,我想检测出 a-zA-Z0-9 根据我的问题,这将被视为非标准符号。

    2 回复  |  直到 6 年前
        1
  •  6
  •   peterSO    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”语句提供多路执行。表达式或类型 将说明符与“switch”中的“cases”进行比较以确定 执行哪个分支。

    表达式开关

    在表达式开关中,计算开关表达式,然后 计算不必是常量的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] 宣布 b 成为一个 switch { } 语句块局部变量。

    对病例表达进行评估,并将其与 true . 如果没有一个是真的,那么 default 被拿走了。

    go与c不同,需要显式 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)
        }
    }
    
        2
  •  3
  •   jub0bs    6 年前

    由于白名单可以很容易地定义为regexp,请使用 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 )