英文:
strings - get characters before a digit
问题
我有一些字符串,如E2 9NZ
,N29DZ
,EW29DZ
。我需要提取第一个数字之前的字符,给出上面的例子:E
,N
,EW
。
我应该使用正则表达式吗?strings包看起来很不错,但似乎不能处理这种情况(提取特定类型之前的所有内容)。
编辑:
为了澄清这个“问题”,我想知道哪种方法更符合Go的习惯,并且可能提供更好的性能。
英文:
I have some strings such E2 9NZ
, N29DZ
, EW29DZ
. I need to extract the chars before the first digit, given the above example : E
, N
, EW
.
Am I supposed to use regex ? The strings package looks really nice but just doesn't seem to handle this case (extract everything before a specific type).
Edit:
To clarify the "question" I'm wondering what method is more idiomatic to go and perhaps likely to provide better performance.
答案1
得分: 7
例如,
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 ""
。
英文:
For example,
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"))
}
Output:
E
N
EW
WXYZ
If there is no digit, example "WXYZ"
, and you don't want anything returned, change return s
to return ""
.
答案2
得分: 1
我们不需要正则表达式来解决这个问题。你可以轻松地遍历一个rune切片,并使用unicode.IsDigit()函数检查当前字符是否为数字,如果是数字,则返回。如果不是数字,则继续循环。如果没有数字,则返回原始参数。
代码
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"))))
}
英文:
We don't need regex for this problem. You can easily walk through on a slice of rune and check the current character with unicode.IsDigit(), if it's a digit: return. If it isn't: continue the loop. If there are no numbers: return the argument
Code
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"))))
}
答案3
得分: 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
英文:
Not sure why almost everyone provided answers in everything but Go. Here is regex-based Go version:
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")
}
}
Running:
<!-- language: lang-none -->
% go run main.go
Found: EW
答案4
得分: 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
}
这段代码与循环版本几乎等效,并消除了在我的先前答案中每个字符上进行匹配的长字符串搜索。但我认为它看起来比循环版本更清晰,这显然是一种品味问题。
英文:
I think the best option is to use the index returned from strings.IndexAny
which will return the first index of any character in a string.
func BeforeNumbers(str string) string {
value := strings.IndexAny(str,"0123456789")
if value >= 0 && value <= len(str) {
return str[:value]
}
return str
}
Will slice the string and return the subslice up to (but not including) the first character that's in the string "0123456789"
which is any number.
Way later edit:
It would probably be better to use IndexFunc rather than 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
}
This is more or less equivalent to the loop version, and eliminates a search over a long string to check for a match every character from my previous answer. But I think it looks cleaner than the loop version, which is obviously a manner of taste.
答案5
得分: 0
以下代码将继续获取字符,直到遇到数字为止。
int i = 0;
String string2test = "EW29DZ";
String stringOutput = "";
while (!Character.isDigit(string2test.charAt(i)))
{
stringOutput = stringOutput + string2test.charAt(i);
i++;
}
英文:
The code below will continue grabbing characters until it reaches a digit.
int i = 0;
String string2test = "EW29DZ";
String stringOutput = "";
while (!Character.isDigit(string2test.charAt(i)))
{
stringOutput = stringOutput + string2test.charAt(i);
i++;
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论