字符串 - 在数字前获取字符

时间:2014-03-10 19:08:17

标签: go

我有一些字符串E2 9NZN29DZEW29DZ。在上面的示例中,我需要在第一个数字之前提取字符:ENEW。 我应该使用正则表达式吗? strings包看起来非常好,但似乎没有处理这种情况(在特定类型之前提取所有内容)。

修改

澄清“问题”我想知道哪种方法更适合go并且可能提供更好的性能。

5 个答案:

答案 0 :(得分:6)

例如,

package main

import (
    "fmt"
    "unicode"
)

func DigitPrefix(s string) string {
    for i, r := range s {
        if unicode.IsDigit(r) {
            return s[:i]
        }
    }
    return s
}

func main() {
    fmt.Println(DigitPrefix("E2 9NZ"))
    fmt.Println(DigitPrefix("N29DZ"))
    fmt.Println(DigitPrefix("EW29DZ"))
    fmt.Println(DigitPrefix("WXYZ"))
}

输出:

E
N
EW
WXYZ

如果没有数字,例如"WXYZ",并且您不想要返回任何内容,请将return s更改为return ""

答案 1 :(得分:1)

我们不需要正则表达式来解决这个问题。您可以轻松地在一片符文上走过,并使用unicode.IsDigit()检查当前字符,如果它是一个数字:return。如果不是:继续循环。如果没有数字:返回参数

代码

package main

import (
"fmt"
"unicode"
)

func UntilDigit(r []rune) []rune {
   var i int
   for _, v := range r {
    if unicode.IsDigit(v) {
        return r[0:i]
    }
    i++
   }
   return r
}

func main() {
fmt.Println(string(UntilDigit([]rune("E2 9NZ"))))
fmt.Println(string(UntilDigit([]rune("N29DZ"))))
fmt.Println(string(UntilDigit([]rune("EW29DZ"))))
}

Playground link

答案 2 :(得分:1)

不确定为什么除了Go之外几乎所有人都提供了答案。这是基于正则表达式的Go版本:

package main

import (
    "fmt"
    "regexp"
)

func main() {
    pattern, err := regexp.Compile("^[^\\d]*")
    if err != nil {
        panic(err)
    }

    part := pattern.Find([]byte("EW29DZ"))
    if part != nil {
        fmt.Printf("Found: %s\n", string(part))
    } else {
        fmt.Println("Not found")
    }
}

运行:

% go run main.go 
Found: EW

Go playground

答案 3 :(得分:1)

我认为最好的选择是使用从strings.IndexAny返回的索引,它将返回字符串中任何字符的第一个索引。

func BeforeNumbers(str string) string { 
    value := strings.IndexAny(str,"0123456789")
    if value >= 0 && value <= len(str) {
        return str[:value]
    }

    return str
}

将对字符串进行切片并将子切片返回到(但不包括)字符串"0123456789"中的任何数字的第一个字符。

稍后编辑:

使用IndexFunc而不是IndexAny可能会更好:

func BeforeNumbers(str string) string { 
    indexFunc := func(r rune) bool {
       return r >= '0' && r <= '9'
    }
    value := strings.IndexFunc(str,indexFunc)
    if value >= 0 && value <= len(str) {
        return str[:value]
    }

    return str
}

这或多或少等同于循环版本,并且消除了对长字符串的搜索,以检查我之前答案中每个字符的匹配。但我认为它看起来比循环版本更清晰,这显然是一种品味。

答案 4 :(得分:0)

下面的代码将继续抓取字符,直到达到数字为止。

int i = 0;
String string2test = "EW29DZ";
String stringOutput = "";

while (!Character.isDigit(string2test.charAt(i))) 
   {
   stringOutput = stringOutput + string2test.charAt(i);
   i++;
   }