获取数字之前的字符。

huangapple go评论162阅读模式
英文:

strings - get characters before a digit

问题

我有一些字符串,如E2 9NZN29DZEW29DZ。我需要提取第一个数字之前的字符,给出上面的例子:ENEW
我应该使用正则表达式吗?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"))))
}

Playground链接

英文:

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"))))
}

Playground link

答案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

Go playground链接

英文:

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

Go playground

答案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,&quot;0123456789&quot;)
    if value &gt;= 0 &amp;&amp; value &lt;= 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 &quot;0123456789&quot; 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 &gt;= &#39;0&#39; &amp;&amp; r &lt;= &#39;9&#39;
    }
    value := strings.IndexFunc(str,indexFunc)
    if value &gt;= 0 &amp;&amp; value &lt;= 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 = &quot;EW29DZ&quot;;
String stringOutput = &quot;&quot;;

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

huangapple
  • 本文由 发表于 2014年3月11日 03:08:17
  • 转载请务必保留本文链接:https://go.coder-hub.com/22309108.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定