2015-11-22 37 views
6

これはよくある問題だと思いますが、私はかなりのウェブページを見つけました。RのREGEX:文字列から単語を抽出する

私はREGEXを初めて使いました。これをRで使用して、最初の数語を文から抽出したいと思います。例えば

、私の文章は

z = "I love stack overflow it is such a cool site" 

ID私は最後の4が必要な場合(私は最初の4つのワードを必要とする場合)

[1] "I love stack overflow" 

か(あるとして、私の出力を持っているのが好きであれば言葉)当然の

[1] "such a cool site" 

、以下の作品

paste(strsplit(z," ")[[1]][1:4],collapse=" ") 
paste(strsplit(z," ")[[1]][7:10],collapse=" ") 

しかし、私は非常に巨大なファイルに対処する必要があるとして、私は、パフォーマンスの問題のための正規表現のソリューションを試してみたいと思います(ともそれについて知るために)私は を含め、いくつかのリンクを見て

Regex to extract first 3 words from a stringhttp://osherove.com/blog/2005/1/7/using-regex-to-return-the-first-n-words-in-a-string.html

はので、私は他のものを試してみましたが、それは通常どちらかの文字列全体を私に返さ

gsub("^((?:\S+\s+){2}\S+).*",z,perl=TRUE) 
Error: '\S' is an unrecognized escape in character string starting ""^((?:\S" 

のようなものを試してみました、または空文字列。

substrのもう1つの問題は、リストを返すことです。多分大規模なファイルを扱い、適用することをするとき[[]]オペレータが物事をちょっと遅くする(??)ように見えるかもしれません。

Rで使用されている構文が多少異なるようですか?感謝! ありがとう!

+2

R正規表現ではダブルエスケープを使用する必要があります。 '\ S' - >' \\ S' –

+0

使いやすく、正規表現を知る必要のない 'stringi :: stri_extract_all_words(z)[[1]] [1:4]'を試すこともできます。あなたは言葉を別々の価値観にするでしょうが。 –

+0

私はあなたの以前の質問で共有していたのと同じアイデアを使用できませんでしたか?(http://stackoverflow.com/questions/33785594/manipulate-char-vectors-inside-a-data-table-object-in -r)?すでに@stribizhevによって指摘されているように、Rのバックスラッシュを二重にするだけです。 – A5C1D2H2I1M1N2O1R2T1

答えて

5

あなたはすでに答えを受け入れてきましたが、私はあなたが実際にあなたに答えを得るために非常に近かったので、あなたは、Rで正規表現についてもう少し理解する手助けする手段としてこれを共有するつもりです自分の。

  1. あなたは、単一のバックスラッシュ(\)を使用:


    はあなたのgsubアプローチには二つの問題があります。 Rは特殊文字なのでエスケープする必要があります。別のバックスラッシュ(\\)を追加してエスケープします。 nchar("\\")を実行すると、 "1"が返されます。

  2. 置き換えの対象は指定していません。ここでは何も置き換えたくはありませんが、文字列の特定の部分を取得したいと考えています。グループは括弧(...)で取り込み、グループの番号で参照できます。ここにはグループが1つしかないので、それを"\\1"と呼んでいます。 "Z" の内容の開始から

    • 仕事:

      sub("^((?:\\S+\\s+){2}\\S+).*", "\\1", z, perl = TRUE) 
      # [1] "I love stack" 
      

      これは、本質的に言っている:

はあなたのような何かを試している必要があります。

  • スタート作成グループ1
  • は(\S+\s+)を2回{2}空白が続く(単語等)の非空白と非空白の後、次のセット(\S+)を探します。これは、3番目の単語の後に空白をもらうことなく、3つの単語を得るでしょう。したがって、異なる単語数を使用する場合は、{2}を、実際に適用されている数よりも1少ない数に変更します。
  • エンドグループ1があります。
  • 次に、グループ1(\1)の内容を "z"から戻します。

  • だけでキャプチャグループの位置を切り替えると一致するパターンの最後にそれを置く、最後の三つの単語を取得すること。

    sub("^.*\\s+((?:\\S+\\s+){2}\\S+)$", "\\1", z, perl = TRUE) 
    # [1] "a cool site" 
    
    +0

    ありがとうございます。 @Ananda Mahto。あなたは同じ関数 'sub'を使って最後の4単語の正規表現を与えることができますか? –

    +1

    @FaguiCurtain、私はちょうど '^。*((?:\\ S + \\ s +){2} \\ S +)$'のように、参照の固定を取り消して、行の始めから終りに置き換えました。 "2"を "3"に変更して、3の代わりに4つの単語を取得します。 – A5C1D2H2I1M1N2O1R2T1

    3

    最初の4つの単語を取得します。

    library(stringr) 
    str_extract(x, "^\\s*(?:\\S+\\s+){3}\\S+") 
    

    最後の4つを取得してください。

    str_extract(x, "(?:\\S+\\s+){3}\\S+(?=\\s*$)") 
    
    +0

    または 'sub("^\\ s *((?:\\ S + \\ s +){3} \\ S +) 。* "、" \\ 1 "、x)' –

    +0

    あなたは私に関数 'sub'を使って正しい正規表現を与えることができますか?私は10,000サンプルのテストを行い、基底Rの 'sub'関数は'ライブラリ(stringr) 'の' str_extract'より30倍高速です。ありがとう –

    +0

    私はばかだが、機能を調整する方法を知らない。置換= ""、z、perl = TRUE) '返されている' '私は大好きです(' '?スタックオーバーフローは "すべてですが最後の4ワード... –

    関連する問題