18823


Twitterのリプライなどの@から始まるユーザ名や画像,やウェブページなどのhttp(s)で始まる文字列を削除したいと考えています。

いろいろためして見ましたがなかなかすべてにマッチするものを見つけられませんでした。

[code]

    target := []string{"@abcde ああああ https://t.co/aaa あああ", "いいいい @abcde ssadsa", "https://t.co/bbb うううう @abcde", "sadw@dasdwdw"}
    
[/code]

このような文字列から上記のような文字列を削除したいと考えています。最後のsadw@dasdwdwは削除しないようにしたいです。

このような場合どのような正規表現を作成すればいいのでしょうか。


CC BY-SA 3.0
2015-11-14T14:26:46.487
18816
2015-11-15T11:18:24.960
7232
question
go 正規表現
正規表現について教えて下さい。


削除したい文字列の前後が、空白文字（行頭・行末・改行含む）であるなら、正規表現そのものは、次でいけると思います。（Go
でのコーディングは私にはわかりませんので、他の回答に譲ります）

[code]

    (^|\s)(@.+?|https?.*?)($|\s)
    
[/code]

<https://regex101.com/r/wI8eD3/1>

[![画像の説明をここに入力](https://i.stack.imgur.com/Hm9Th.png)](https://i.stack.imgur.com/Hm9Th.png)

ちなみに、`http(s)`の部分をほんの少し厳密に、`https?://`として、`://`まで含めてもいいかもしれません。


CC BY-SA 3.0
2015-11-14T14:47:40.437
18817
2015-11-14T14:53:07.450
2015-11-14T14:53:07.450
7290
7290
18816
answer


hata さんの答えを go でコーディングしてみると、そのまま実行できました。

[code]

    package main
    
    import (
        "fmt"
        "regexp"
    )
    
    func main() {
    
        tweets := []string{
            "@abcde ああああ https://t.co/aaa あああ",
            "いいいい @abcde ssadsa",
            "https://t.co/bbb うううう @abcde",
            "sadw@dasdwdw",
        }
    
        assigned := regexp.MustCompile("(^|\\s)(@.+?|https?.*?)($|\\s)")
    
        for _, tweet := range tweets {
            replaced := assigned.ReplaceAllString(tweet,  "")
            fmt.Println(replaced)
        }
    }
    
[/code]

出力:

[code]

    あああああああ
    いいいいssadsa
    うううう
    sadw@dasdwdw
    
[/code]

<http://play.golang.org/p/HWvLTsxXmt>


CC BY-SA 3.0
2015-11-14T15:40:50.617
18821
2015-11-14T15:46:31.823
2015-11-14T15:46:31.823
754
754
18816
answer


問題点を見つけたのですが、正規表現だけではどうにも対応ができませんでしたので、面倒くさい事をしています。

[code]

    re, _ := regexp.Compile(`(^|\s)(@|https?://)\S+`)
    re2, _ := regexp.Compile(`^\s*|\s*$`)
    for _, v := range target {
      // "いいいい @abcde ssadsa" => "いいいい ssadsa"
      fmt.Printf("   Replace: %#v\n",
        re2.ReplaceAllString(re.ReplaceAllString(v, ""), ""))
    
      // "いいいい @abcde ssadsa" => "いいいいssadsa"
      splitted := re.Split(v, -1)
      for i, v := range splitted {
        splitted[i] = re2.ReplaceAllString(v, "")
      }
      fmt.Printf("Split&Join: %#v\n", strings.Join(splitted, ""))
    }
    
[/code]

実は、以下の正規表現を使用して、

[code]

    (^|\s)(@.+?|https?.*?)($|\s)
    
[/code]

以下の文字列に対して `ReplaceAllString()` を実行すると、

[code]

    "@abcde https://t.co/aaa あああ"
    => "https://t.co/aaa あああ"
    
[/code]

となってしまいます。本来は、

[code]

    "あああ"
    
[/code]

となるはずです。理由は、、お分かりかと思います。

**追記**

Perl で試してみると、

[code]

    $str = '@abcde https://t.co/aaa あああ';
    $str =~ s/(^|\s)(@.+?|https?.*?)($|\s)//g;
    print $str . "\n";
    => https://t.co/aaa あああ
    
[/code]

同じ結果になります。そこで、否定的先読み(negative lookahead)を用いると、期待する結果が得られます。

[code]

    $str = '@abcde https://t.co/aaa あああ';
    $str =~ s/((^|\s)(@|https?:\/\/)\S+)|(\s(?!(@|https?:\/\/)))//g;
    print $str . "\n";
    => あああ
    
[/code]

ですが、golang の regexp package では否定的先読みを使うことができません(NOT SUPPORTED)。

そこで、PCRE package を使います。まずは `go get` で package をインストールします。

[code]

    $ go get github.com/glenn-brown/golang-pkg-pcre/src/pkg/pcre
    
[/code]

以下はテストプログラムとその実行結果です。

**test_regexp.go**

[code]

    package main
    
    import (
      "fmt"
    
      "github.com/glenn-brown/golang-pkg-pcre/src/pkg/pcre"
    )
    
    func main() {
      target := []string{
        "@abcde https://t.co/aaa あああ",
        "いいいい @abcde ssadsa",
        "https://t.co/bbb うううう @abcde",
        "sadw@dasdwdw",
        "ええ @bar.baz @foo xyz",
        "@bar.baz https://t.co/ccc おお @xyz good@mail.com",
      }
    
      re, _ := pcre.Compile(`((^|\s)(@|https?://)\S+)|(\s(?!(@|https?://)))`, 0)
      for _, v := range target {
        fmt.Printf("  Source: %#v\n", v)
        fmt.Printf("Replaced: %#v\n", string(re.ReplaceAll([]byte(v), []byte(""), 0)))
      }
    }
    
[/code]

**実行結果**

[code]

    $ go run test_regexp.go
      Source: "@abcde https://t.co/aaa あああ"
    Replaced: "あああ"
      Source: "いいいい @abcde ssadsa"
    Replaced: "いいいいssadsa"
      Source: "https://t.co/bbb うううう @abcde"
    Replaced: "うううう"
      Source: "sadw@dasdwdw"
    Replaced: "sadw@dasdwdw"
      Source: "ええ @bar.baz @foo xyz"
    Replaced: "ええxyz"
      Source: "@bar.baz https://t.co/ccc おお @xyz good@mail.com"
    Replaced: "おおgood@mail.com"
    
[/code]


CC BY-SA 3.0
2015-11-14T16:28:18.623
18823
2015-11-15T11:18:24.960
2015-11-15T11:18:24.960
18816
answer