2017-10-13 4 views
3

私は非常に乱雑な文字列のベクトルを持っています。だからここに私がまたは、正しくその後、いくつかのより多くのテキストを入力してもしなくてもよい時間に続いて、いくつかのテキストを、特色の文字列を持っている正規表現でRの文字列の不一致部分をどのように抽出できますか?

library(tidyverse) 
library(stringr) 
strings <- tibble(
    name = c("lorem 11:07:59 86136-1-sed", 
      "ipsum 14:35:57 S VARNAME-ut", 
      "dolor 10:37:53 1513 -2-perspiciatis", 
      "sit 10:48:25", 
      "amet 13:52:1365293-2-unde", 
      "consectetur 11:53:1 16018-2-omnis", 
      "adipiscing 11:19 17237-2-iste" 
      ) 
) 
strings_out <- strings %>% 
    mutate(heads = str_extract(name, "^.*?\\s\\d{1,2}:\\d{1,2}:\\d{1,2}")) %>% 
    mutate(ends = str_replace(name, "^.*?\\s\\d{1,2}:\\d{1,2}:\\d{1,2}", "")) 
strings_out[,2:3] 
#> # A tibble: 7 x 2 
#>     heads       ends 
#>     <chr>       <chr> 
#> 1  lorem 11:07:59     86136-1-sed 
#> 2  ipsum 14:35:57     S VARNAME-ut 
#> 3  dolor 10:37:53   1513 -2-perspiciatis 
#> 4  sit 10:48:25        
#> 5  amet 13:52:13     65293-2-unde 
#> 6 consectetur 11:53:1     16018-2-omnis 
#> 7    <NA> adipiscing 11:19 17237-2-iste 

:ここでは一例です。時間の経過後に文字列の終わりを抽出したいのですが、str_extractを使って潜在的な正規表現によく対応するようなパターンはありません。 headsに示すように、文字列の最初の半分に簡単に一致させることができます。しかし、最後の半分を抽出する唯一の方法は、endsに示すように、空の文字列にstr_replaceを使用することです。

私は、このリストに気付いたすべての一般的なエラーを含めるようにしました:ハイフネーション、スペースまたは文字列の内容が時間の後にない、保証されたスペースと時間と希望の文字列の最後の半分行方不明またはコロンであってもよい。

私がしたいのは、str_extractを使用して、私がstr_replaceのものに近いものを得ることです。主な違いは、この正規表現はまだ動作しないエラーのため、str_extractは私のためにフィルタリングして、手動で修正するのは簡単ですNAを与えることですが、文字列全体でstr_replaceだけコピーが行7

Iに見られるように、 NAを手に入れてExcelなどで手作業で修正するなど、いくつかのハッキーな方法でこれを行うことができると思われますが、検索にもかかわらず文字列の不一致部分を返す方法がわからないことに驚いています(^)[^]を含む異なる正規表現を試してみてください。何か案は?

+2

が得? –

+0

申し訳ありませんが明らかでない場合。最初の列に1があれば、NAを返す以外は2番目の列が望ましい結果になります。私はちょうど通過し、正しい指数でそれらを "NA"で置き換えることができることを理解するが、私は "文字列の比類のない部分を返す"という概念がするのは難しいように思われることがわかった。 –

答えて

1

通常、おそらくlookaroundsを調べたいと思うかもしれませんが、あなたのデータにはもっと便利な構造が必要かもしれません。

は、ここで私は常にそれの後にスペースを持っていない時間を実現する前に書いた簡単な例です:


library(tidyverse) 
library(stringr) 
strings <- tibble(
    name = c("lorem 11:07:59 86136-1-sed", 
      "ipsum 14:35:57 S VARNAME-ut", 
      "dolor 10:37:53 1513 -2-perspiciatis", 
      "sit 10:48:25", 
      "amet 13:52:1365293-2-unde", 
      "consectetur 11:53:1 16018-2-omnis", 
      "adipiscing 11:19 17237-2-iste" 
) 
) 
strings_out <- strings %>% 
    mutate(heads = str_extract(name, "^.*?\\s\\d{1,2}:\\d{1,2}:\\d{1,2}"), 
     ends = str_extract(name, "(?<=:\\d{1,2})[\\s\\S]+$")) 

strings_out[c(1,3)] 
#> # A tibble: 7 x 2 
#>         name     ends 
#>         <chr>    <chr> 
#> 1   lorem 11:07:59 86136-1-sed   86136-1-sed 
#> 2   ipsum 14:35:57 S VARNAME-ut   S VARNAME-ut 
#> 3 dolor 10:37:53 1513 -2-perspiciatis 1513 -2-perspiciatis 
#> 4      sit 10:48:25     <NA> 
#> 5   amet 13:52:1365293-2-unde     <NA> 
#> 6 consectetur 11:53:1 16018-2-omnis  16018-2-omnis 
#> 7  adipiscing 11:19 17237-2-iste   17237-2-iste 

問題は、ここでより多くの構造がなければ5行目のような行です、時間が13:52:1313:52:1かどうかを知ることはできません。両方とも他の文字列に存在するオプションなので、わかりません。どちらが正しいかは、正規表現で解決できる問題ではありません。

+1

ええと私は5行目について何を意味するのか見ています。私が知る限り、数字の後に5つ以上はないので、正規表現を書きました。私はlookbehindが私が以前に気づいていなかったツールだと思っています。これは私が望むように 'str_extract'の使用を許可しています。私は良い方法がないかもしれないと思います "比類のない抽出し、それだけで目的の一致を見つけるために正規表現を変更する必要がありますか? –

1

また、これを試すことができます。

library(tidyverse) 
library(stringr) 

regex = "^\\w+\\s\\d{2}:\\d{2}:*\\d{0,2}" 

strings %>% 
    mutate(head = str_extract(name, regex), 
     end = str_replace(name, paste0(regex, "\\s?"), ""), 
     end = str_replace(end, "^\\s*$", NA_character_)) 

結果:

# A tibble: 7 x 3 
           name    head     end 
           <chr>    <chr>    <chr> 
1   lorem 11:07:59 86136-1-sed  lorem 11:07:59   86136-1-sed 
2   ipsum 14:35:57 S VARNAME-ut  ipsum 14:35:57   S VARNAME-ut 
3 dolor 10:37:53 1513 -2-perspiciatis  dolor 10:37:53 1513 -2-perspiciatis 
4      sit 10:48:25  sit 10:48:25     <NA> 
5   amet 13:52:1365293-2-unde  amet 13:52:13   65293-2-unde 
6 consectetur 11:53:1 16018-2-omnis consectetur 11:53:1  16018-2-omnis 
7  adipiscing 11:19 17237-2-iste adipiscing 11:19   17237-2-iste 

注:

私のソリューションは、行5のために動作しますが、あなたがいるかどうかを決定する必要がありますこの場合は13:52:13または13:52:1を抽出します。いずれの場合も、正規表現を単純に変更するだけで済むが、@ Zachのように、自動的な方法はない。

0

あなたはただ一つの追加の行でそれを持つことができます。

strings["rx"] <- str_match(strings$name, "\\d*:\\d*(?::\\d+)?(.*)")[,2] 
strings 

望ましい結果は何

# A tibble: 7 x 2 
           name     rx 
           <chr>     <chr> 
1   lorem 11:07:59 86136-1-sed   86136-1-sed 
2   ipsum 14:35:57 S VARNAME-ut   S VARNAME-ut 
3 dolor 10:37:53 1513 -2-perspiciatis 1513 -2-perspiciatis 
4      sit 10:48:25      
5   amet 13:52:1365293-2-unde    -2-unde 
6 consectetur 11:53:1 16018-2-omnis   16018-2-omnis 
7  adipiscing 11:19 17237-2-iste   17237-2-iste 
+0

行5については? – useR

関連する問題