2016-07-27 27 views
1

私はGolangを学んでいるので、シェルスクリプトのいくつかを書き直すことができます。Golangの文字列の一部を抽出しますか?

私はURLのことのようになります:

echo "$myString" | grep -o 'http://.*.txt' 
:私はこのような何かをするだろう、シェルスクリプトで

https://example-1.example.com/a/c482dfad3573acff324c/list.txt 

https://example-1.example.com/a/c482dfad3573acff324c/list.txt?parm1=value,parm2=value,parm3=https://example.com/a?parm1=value,parm2=value 

私は、次の部分を抽出したいです

Golangで同じことをする最良の方法は、標準ライブラリを使用することだけです。

答えて

6

いくつかのオプションがあります:それはすべての可能なコーナーケースを処理するため

// match regexp as in question 
pat := regexp.MustCompile(`https?://.*\.txt`) 
s := pat.FindString(myString) 

// everything before the query 
s := strings.Split(myString, "?")[0] string 

// same as previous, but avoids []string allocation 
s := myString 
if i := strings.IndexByte(s, '?'); i >= 0 { 
    s = s[:i] 
} 

// parse and clear query string 
u, err := url.Parse(myString) 
u.RawQuery = "" 
s := u.String() 

は、最後のオプションが最適です。

try it on the playground

+0

Iだろうと、任意の奇妙なエッジケースを処理するためurl.Parseを使用することをお勧めしますこれは正規表現や分割によって見逃される可能性があります。たとえば、? –

+0

私は、url.Parseが最良のアプローチであることに同意します。リストされたすべてのオプションは '? 'のないURLを処理します。 –

1

あなたはstrings.IndexRunestrings.IndexBytestrings.Splitstrings.SplitAfterstrings.FieldsFuncurl.Parseregexpたり、機能を使用することができます。

最初の最も簡単な方法:
あなたは(コメントを出力して)このようなi := strings.IndexRune(s, '?')またはその後i := strings.IndexByte(s, '?')s[:i]を使用することがあります。

package main 

import "fmt" 
import "strings" 

func main() { 
    s := `https://example-1.example.com/a/c482dfad3573acff324c/list.txt?parm1=value,parm2=value,parm3=https://example.com/a?parm1=value,parm2=value` 
    i := strings.IndexByte(s, '?') 
    if i != -1 { 
     fmt.Println(s[:i]) // https://example-1.example.com/a/c482dfad3573acff324c/list.txt 
    } 
} 

またはあなたが使用することがurl.Parse(s)(私はこれを使用すると思います):

package main 

import "fmt" 
import "net/url" 

func main() { 
    s := `https://example-1.example.com/a/c482dfad3573acff324c/list.txt?parm1=value,parm2=value,parm3=https://example.com/a?parm1=value,parm2=value` 
    url, err := url.Parse(s) 
    if err == nil { 
     url.RawQuery = "" 
     fmt.Println(url.String()) // https://example-1.example.com/a/c482dfad3573acff324c/list.txt 
    } 
} 

またはあなたが使用することregexp.MustCompile(".*\\.txt")

package main 

import "fmt" 
import "regexp" 

var rgx = regexp.MustCompile(`.*\.txt`) 

func main() { 
    s := `https://example-1.example.com/a/c482dfad3573acff324c/list.txt?parm1=value,parm2=value,parm3=https://example.com/a?parm1=value,parm2=value` 

    fmt.Println(rgx.FindString(s)) // https://example-1.example.com/a/c482dfad3573acff324c/list.txt 
} 

またはあなたがsplits := strings.FieldsFunc(s, func(r rune) bool { return r == '?' })splits[0]を使用することがあります。

package main 

import "fmt" 
import "strings" 

func main() { 
    s := `https://example-1.example.com/a/c482dfad3573acff324c/list.txt?parm1=value,parm2=value,parm3=https://example.com/a?parm1=value,parm2=value` 
    splits := strings.FieldsFunc(s, func(r rune) bool { return r == '?' }) 
    fmt.Println(splits[0]) // https://example-1.example.com/a/c482dfad3573acff324c/list.txt 
} 

あなたがsplits := strings.Split(s, "?")splits[0]を使用することがあります。

package main 

import "fmt" 
import "strings" 

func main() { 
    s := `https://example-1.example.com/a/c482dfad3573acff324c/list.txt?parm1=value,parm2=value,parm3=https://example.com/a?parm1=value,parm2=value` 
    splits := strings.Split(s, "?") 
    fmt.Println(splits[0]) // https://example-1.example.com/a/c482dfad3573acff324c/list.txt 
} 

あなたがsplits := strings.SplitAfter(s, ".txt")splits[0]を使用することがあります。

package main 

import "fmt" 
import "strings" 

func main() { 
    s := `https://example-1.example.com/a/c482dfad3573acff324c/list.txt?parm1=value,parm2=value,parm3=https://example.com/a?parm1=value,parm2=value` 
    splits := strings.SplitAfter(s, ".txt") 
    fmt.Println(splits[0]) // https://example-1.example.com/a/c482dfad3573acff324c/list.txt 
} 

たりしてもよいですあなたの関数を使用する(ほとんど依存しない方法):

package main 

import "fmt" 

func left(s string) string { 
    for i, r := range s { 
     if r == '?' { 
      return s[:i] 
     } 
    } 
    return "" 
} 

func main() { 
    s := `https://example-1.example.com/a/c482dfad3573acff324c/list.txt?parm1=value,parm2=value,parm3=https://example.com/a?parm1=value,parm2=value` 
    fmt.Println(left(s)) // https://example-1.example.com/a/c482dfad3573acff324c/list.txt 
} 
1

あなたはURLのみをprosessingしている場合は、クエリとフラグメントの部分を切り捨て、URLを解析するために行くのnet/urlライブラリhttps://golang.org/pkg/net/url/を使用することができます(クエリparm1=value,parm2=valueなどだろう)、及び()次の例のように、https://play.golang.org/p/Ao0jU22NyA残り部分scheme://host/pathを抽出:

package main 

import (
    "fmt" 
    "net/url" 
) 

func main() { 
    u, _ := url.Parse("https://example-1.example.com/a/b/c/list.txt?parm1=value,parm2=https%3A%2F%2Fexample.com%2Fa%3Fparm1%3Dvalue%2Cparm2%3Dvalue#somefragment") 
    u.RawQuery, u.Fragment = "", "" 
    fmt.Printf("%s\n", u) 
} 

出力:

https://example-1.example.com/a/b/c/list.txt 
関連する問題