2017-08-24 79 views
1

我想用正則表達式來解析文件使用正則表達式。在R中使用正則表達式的大多數解決方案都使用stringr包。我還沒有找到另一種方式,或另一個包使用,將工作。如果你有另一種解決這個問題的方法,那也是可以接受的。使用str_extract_all在R中運行正則表達式有regexp尚未實現

我想要完成的是抓住兩個由空格分隔的值,最後一個值是逗號分隔的可變長度值。這應該像當前的格式一樣進入矩陣或df表格中。

foo  foo_123bar  foo,bar,bazz 
foo2 foo_456bar  foo2,bar2 

我有我的正則表達式的工作示例here.

有可能是一對夫婦的我可以運行到的問題。首先可能是我寫的正則表達式不受R的正則表達式引擎支持。雖然我有從this那裏得到支持的感覺。我已經看到R使用了一種類似POSIX的格式,可以讓事情變得有趣。第二個簡單的可能正是錯誤信息正在顯示的內容。這不是已編碼的功能。然而,這將是最麻煩的,因爲我不知道另一種方法來解決我的問題沒有這個包。

下面是我使用複製這種錯誤

library("stringr") 

string = " foo foo_123bar  foo,bar,bazz\n foo2 foo_456bar  foo2,bar2,bazz2" 

pattern = " 
    (?(DEFINE) 
    (?<blanks>[[:blank:]]+) 
    (?<var>\"?[[:alnum:]_]+\"?) 
    (?<csvar>(\"?[[:alnum:]_]+\"?,?)+) 
) 
^
    (?&blanks)((?&var)) 
    (?&blanks)((?&var)) 
    (?&blanks)((?&csvar))" 

# Both of these are throwing the error 
str_extract_all(string, pattern) 
str_extract_all(string, regex(pattern, multiline=TRUE, comments=TRUE)) 

> Error in stri_extract_all_regex(string, pattern, simplify = simplify, : 
> Use of regexp feature that is not yet implemented. (U_REGEX_UNIMPLEMENTED) 


# Using the example from ?str_extract_all runs without error 
shopping_list <- c("apples x4", "bag of flour", "bag of sugar", "milk x2") 
str_extract_all(shopping_list, "\\b[a-z]+\\b", simplify = TRUE) 

我要尋找一個解決辦法,不一定是stringr解決方案將R代碼,但是這是我發現的唯一途徑適合我的需要。其他更簡單的R正則表達式函數只接受該模式,而不接受包含我正在使用的多行和註釋功能的額外參數。

+0

您正在嘗試使用ICU正則表達式庫解析PCRE特定的正則表達式。那是不可能的。可以將它與基地R regmatches一起使用,也可以重新使用,以遵循ICU語法。 ICU不支持遞歸,因此您不能像在PCRE模式中那樣重複使用模式。 –

+0

這是否按預期工作 - https://ideone.com/lT6RxR? –

+0

引擎太多,都有自己的規則。我正在使用定義樣式遞歸來使我的正則表達式更易於閱讀和理解。實際上,我有7組這些值,這隻會變得更加混亂。 ICU有辦法制作更多模塊化正則表達式嗎? @Wiktor您在評論時回覆。這確實有用。它似乎破壞了整個stringr庫,但我沒有問題。 – user2716722

回答

1

您有一個PCRE正則表達式,只能用於使用PCRE正則表達式庫(或Boost,基於PCRE)解析正則表達式的方法/函數中使用。 stringrstr_extract用ICU正則表達式庫解析正則表達式。 ICU正則表達式不支持遞歸和DEFINE塊。您不能使用模式內方法來定義子模式,然後重新使用它們。

相反,只是聲明你需要重新使用作爲變量的正則表達式部分和動態構建模式:

library("stringr") 
string = " foo foo_123bar  foo,bar,bazz\n foo2 foo_456bar  foo2,bar2,bazz2" 
blanks <- "[[:blank:]]+" 
vars <- "\"?[[:alnum:]_]+\"?" 
csvar <- "(?:\"?[[:alnum:]_]+\"?,?)+" 
pattern <- paste0("^",blanks,"(", vars, ")",blanks,"(", vars,")",blanks,"(",csvar, ")") 
str_match_all(string, pattern) 
# [[1]] 
#  [,1]         [,2] [,3]   [,4]   
#[1,] " foo foo_123bar  foo,bar,bazz" "foo" "foo_123bar" "foo,bar,bazz" 

注意:您需要使用str_match(或str_match_all)提取捕獲組值str_extractstr_extract_all只允許訪問整個匹配值。

+0

str_match_all上的很好的調用。之前我使用它時,事情更簡單,但沒有看到輸出知道我正在使用錯誤的功能。我不特別喜歡paste0方法,因爲它不太清楚正則表達式正在發生什麼。但是,重寫該代碼要好得多。這將是一個更大的混亂 – user2716722

+0

你可以縮進代碼更好一點,添加coments ... –

+0

是的,那是我現在正在做的。但是爲了回答我自己的問題,我確實找到了一個正則表達式構建庫,它是用於構建正則表達式的R包裝器。這可能是最可行的方法。它被稱爲['rex'](https://cran.r-project.org/web/packages/rex/rex.pdf)我可能最終會使用這個,但這完全是一個問題,如果我想學習它或不;) – user2716722