2016-10-11 24 views
0

私は文字ベクトルとして保存したい文字列strEx <- "list(A, B, C, D)"を持っている:R - 文字列操作と抽出

[1] "A" "B" "C" "D" 

私は(だけでなくやり過ぎかもしれない正規表現では非常に良好ではないんだけど、私がします将来的にはそれ以上のものが必要です)、これはおそらく私の問題の一部です。あまりにも多くのコード/悪いフォームであると感じる解決策があります。

私は最後に何が欲しいのですが、コンマで分割して平坦化する必要があります。私はこれがあまりにも粗すぎると感じています。誰もがよりきれいな解決策を持っていますか?

d <- gsub(".*\\((.*)\\).*", "\\1", strEx) 
d1 <- unlist(tstrsplit(d, ", ", type.convert = TRUE, fixed = TRUE)) 
+0

ので、実際のケースでは、あなたはカンマ区切りの値の周りにいくつかのリテラルテキストを持っていますか? –

+1

'res < - str_match_all(strEx、"(?:リスト\\(\\ s *)(?!^)\\ G、?\\ s *)([^、)] +) ")' 'ライブラリ(stringr)'しかし、あなたのアプローチは既にとても良いです。 –

+0

@WiktorStribiżew実際の場合、テキスト(A、B、C、D、...、k)のテキストである可能性があります。文字列の最後の文字は常に1つのブロックof()、終了文字のみであってもよく、そうでなくてもよい。 – ErrantBard

答えて

3

あなたは、このように式を解析できます。

#parse the expression 
pEx <- parse(text = strEx)[[1]] 

式は、実際のシンボルのリストであり、そのように扱うことができます。ここでは、文字にlist以外のすべてを回す:あなたは(あなたも正規表現を使用したソリューションとして提案するものである)文字列を解析する必要がある場合

vapply(pEx[-1], as.character, FUN.VALUE = "") 
#[1] "A" "B" "C" "D" 

はしかし、いくつかの前のステップは、通常は改善されるべきです。解析する必要がある式を持つべきではありません。

はこれを参照してください:

library(fortunes) 
fortune(106) 
#If the answer is parse() you should usually rethink the question. 
# -- Thomas Lumley 
#  R-help (February 2005) 
+0

Thxローランド、私はこれを答えとして受け入れ、あなたは良い点を挙げます。これは主に文字列操作を少し良くするための試行でしたが、私は昨夜この部分を変更して、すべてではないにしてもほとんどの文字列操作を削除しました。 手作業で挿入したデータを消去する必要がある私の前に1GBのcsvがあります。私はそれが最初から正しく行われていればそれが良いと思っていたことに同意しますが、それは数百人の異なる人々によって行われた何年もの挿入の結果です。 – ErrantBard

1

あなたは、すべての文字に引用符を追加し、eval(parse(...))で試すことができます。

unlist(eval(parse(text=gsub("([A-Z])", "\"\\1\"", "list(A, B, C, D)")))) 
#[1] "A" "B" "C" "D" 

あなたが最初の文字列にカンマがいない場合は、カンマを追加し、別のsubステップと最後の1を削除することができます:

unlist(eval(parse(text=sub(",(?=[)])", "", gsub("([A-Z])", "\"\\1\",", "list(A B C D)"), perl=TRUE)))) 
# [1] "A" "B" "C" "D" 
+0

thxしかし、残念ながら、私はこのz < - "list(A、B、C、D)のような文字列として供給するとうまくいかないようで、プログラムで動作する必要があります。あなたの答えはそれがそうであるように動作します。 – ErrantBard

+0

@ErrantBard私は無意識のうちにコンマを追加して申し訳ありません。あなたの文字列にカンマがない場合、私はオプションで編集しました。あなたのためにもっとうまくいくことを願っています – Cath

+0

Thx - 今すぐ動作します:) – ErrantBard

1

2段階アプローチは非常に優れており、読みやすいです。

> g <- unlist(regmatches(strEx, gregexpr("(?:list\\(\\s*|(?!^)\\G(?:,\\s*)?)\\K[^,)]+", strEx, perl=TRUE))) 
> g 
[1] "A" "B" "C" "D" 

パターンが詳細:

あなたがしようと1のテキスト のブロック内グラブアイテムに行きたい場合は、ベース・R機能を使用して \G\K事業者とPCRE正規表現を使用することができます
  • (?:list\\(\\s*|(?!^)\\G(?:,\\s*)?)からlist(と0+空白のストリング(list\\(\\s*部分を参照)、または前成功したマッチの端((?!^)\\Gを参照)、,とZERの任意配列以上のO空白((?:,\\s*)?参照)
  • \\Kから,)以外の1またはそれ以上の文字 - これまで
  • [^,)]+に一致したテキストを省略する。

regex demo onlineを参照してください。

+0

+1その試みの評価とパターンの詳細を含む別のバージョンの両方について、Wiktorの+1は細部の最後の部分が多くを助けました。私は他の人が答えを試みるためにある程度の時間を与えます。私はあなたのことを喜んで受け入れるでしょう – ErrantBard

+0

また、これは基底R関数だけを使う解です。 –