2017-04-10 1 views
2

golangで文字列をトリミングしてかなりの文字列接頭辞を作成するエレガントな方法はありますか?私は開始のためのこの機能を持っています:golangで要求された長さの文字列接頭辞をutf-8のシンボルで扱っています

func prettyCrop(in string, cropLength int) string { 
    if len(in) < cropLength { 
     return in 
    } else { 
     in = in[0:cropLength] 
     in = strings.TrimRightFunc(in, func(r rune) bool { 
      if r == ' ' { 
       return true 
      } 
      return false 
     }) 
     return in + "…" 
    } 
} 

それは十分に英語のテキストのために働くが、何かより複雑な問題がある。この例を参照してください。

prettyCrop("čřč čřč", 8) //čř?… 

ここで期待したとおりにTrimRightFuncが機能しません。私はそれがčřčを返すと期待しています。この関数が有効なutf-8文字列を返さないのはなぜですか?これのための図書館はありますか?どうすれば修正できますか?より良い解決策はありますか?

答えて

2

問題は、stringスライス列ではなく、文字やstringrune Sを表し、UTF-8でエンコードされたバイトのスライスをスライス。 stringにUTF-8エンコーディングで複数バイトで表される文字が含まれている場合、stringをスライス/カットすると無効なUTF-8エンコードされたシーケンスが生成される可能性があります。

func prettyCrop(in string, cropLength int) string { 
    in2 := []rune(in) 
    if len(in2) < cropLength { 
     return in 
    } else { 
     in2 = in2[:cropLength] 
     in = strings.TrimRightFunc(string(in2), func(r rune) bool { 
      if r == ' ' { 
       return true 
      } 
      return false 
     }) 
     return in + "…" 
    } 
} 

テストそれ::

cropLengthは文字制限(とないバイト数の制限)であることを意味し、あなたが最初 []runestringを変換し、その上で動作しなければならないと仮定すると、

for i := 0; i < 7; i++ { 
    fmt.Println(prettyCrop("čřč čřč", i)) 
} 

出力(Go Playground上でそれを試してみてください):

… 
č… 
čř… 
čřč… 
čřč… 
čřč č… 
čřč čř… 

パフォーマンスノート:ので、上記の例は、「パフォーマンス」友好的ではないです

:それは[]runeに全体in文字列を変換し

  • 、それだけで、その最初のcropLengthルーンを取得するのに十分だろうa for range
  • strings.TrimRightFunc()を呼び出すには、[]runestringに戻す必要があります。次に、文字列連結を実行して結果を生成します。これは手動で[]runeをループして回避することができ、返される単一のstringを作成するだけで済みます。
関連する問題