Go'da alt dizeleri ayıklama


114

Konsoldan bir satırın tamamını (beyaz boşluklar dahil) okumaya ve sonra işlemeye çalışıyorum. Bufio.ReadString'i kullanarak, satırsonu karakteri girişle birlikte okunur, bu yüzden satırsonu karakterini kırpmak için aşağıdaki kodu buldum:

input,_:=src.ReadString('\n')
inputFmt:=input[0:len(input)-2]+"" //Need to manually add end of string

Bunu yapmanın daha deyimsel bir yolu var mı? Yani, sizin için alt dizeleri çıkarırken biten boş bayt ile ilgilenen bir kitaplık zaten var mı?

(Evet, go readline -> string'de satırsonu karakteri olmadan bir satırı okumanın bir yolu olduğunu biliyorum, ancak daha çok zarif dize manipülasyonu arıyorum.)

Yanıtlar:


146

Görünüşe göre dilimlerin çalışması ve C'dekinden farklı olan dize depolama biçimi kafanız karışmış gibi görünüyor.

  • Go'daki herhangi bir dilim uzunluğu (bayt cinsinden) depolar, böylece lenişlemin maliyetini önemsemeniz gerekmez: saymaya gerek yoktur
  • Go dizeleri boş olarak sonlandırılmaz, bu nedenle boş bir baytı kaldırmanız gerekmez ve 1dilimlemeden sonra boş bir dize ekleyerek eklemeniz gerekmez .

Son karakteri kaldırmak için (eğer bir baytlık bir karakter ise),

inputFmt:=input[:len(input)-1]

11
0'a (veya :) ihtiyacınız bile s = s[:len(s)-1]yok, yeter.
uriel

8
Lütfen bu yöntemin Unicode dizeleri ile çalışmayacağını unutmayın! groups.google.com/forum/#!msg/golang-nuts/ZeYei0IWrLg/…
Melllvar

@Melllvar Bu yüzden "eğer bir baytlık bir karakterse" kesin olarak karar verdim . Birden fazla bayt alan bir karakteri kaldırmak istiyorsanız (bu OP'nin durumu değildir), adapte olmalısınız.
Denys Séguret

25

Go dizeleri boş olarak sonlandırılmaz ve bir dizenin son karakterini kaldırmak için şunları yapabilirsiniz:

s = s[:len(s)-1]

10
Bu yanlıştır ve hatalara neden olur. Bu , dizeden son baytı çıkarır ve bu da onu geçersiz UTF-8 (veya diğer çok baytlı kodlama) haline getirebilir.
dr. Sybren

3
Bunun nasıl bozulduğuna dair bir örnek için play.golang.org/p/K3HBBtj4Oi adresine bakın .
dr. Sybren

10

Sıfır uzunluklu girişte paniği önlemek için, kesme işlemini bir if satırına sarın.

input, _ := src.ReadString('\n')
var inputFmt string
if len(input) > 0 {
    inputFmt = input[:len(input)-1]
}
// Do something with inputFmt

9

Bu, Go'da alt dizeyi gerçekleştirmek için basit olanıdır

package main

import "fmt"

var p = fmt.Println

func main() {

  value := "address;bar"

  // Take substring from index 2 to length of string
  substring := value[2:len(value)]
  p(substring)

}

7

UYARI: yalnızca dizeler üzerinde çalışmak, yalnızca ASCII ile çalışır ve giriş, ASCII UTF-8 kodlu olmayan bir karakter olduğunda yanlış sayılır ve çok baytlı karakterleri orta sıradaki karakterleri kestiği için muhtemelen karakterleri bile bozacaktır.

İşte UTF-8 uyumlu bir sürüm:

func substr(input string, start int, length int) string {
    asRunes := []rune(input)

    if start >= len(asRunes) {
        return ""
    }

    if start+length > len(asRunes) {
        length = len(asRunes) - start
    }

    return string(asRunes[start : start+length])
}

1
Bunun daha fazla oy kullanması gerekiyor - utf-8 bilinçli bölme kullanmayarak kötü bir şekilde ısırıldım.
kolaente


2

8 yıl sonra bu cevherle karşılaştım ve yine de OP'nin orijinal sorusunun gerçekten cevaplandığına inanmıyorum:

bu yüzden yeni satır karakterini kırpmak için aşağıdaki kodu buldum

Ederken bufio.Readertip destekler ReadLine() yöntem ki kaldırır, hem \r\nve \ntekrarlayan kontrol gerekli olduğundan kullanımı zor olan düşük düzeyli bir fonksiyonu olarak ifade edilir.

IMO, boşlukları kaldırmanın deyimsel bir yolu, Golang'ın dizeler kitaplığını kullanmaktır:

input, _ = src.ReadString('\n')

// more specific to the problem of trailing newlines
actual = strings.TrimRight(input, "\r\n")

// or if you don't mind to trim leading and trailing whitespaces 
actual := strings.TrimSpace(input)

Golang oyun alanında bu örneğe bakın: https://play.golang.org/p/HrOWH0kl3Ww

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.