簡體   English   中英

使用變量在 R 中創建正則表達式模式

[英]Using variable to create regular expression pattern in R

我有一個功能:

ncount <- function(num = NULL) {

 toRead <- readLines("abc.txt")
 n <- as.character(num)
 x <- grep("{"n"} number",toRead,value=TRUE)

}

grep-ing 時,我希望函數中傳遞的 num 動態創建要搜索的模式? 這如何在 R 中完成? 文本文件的每一行都有數字和文本

您可以使用paste連接字符串:

grep(paste("{", n, "} number", sep = ""),homicides,value=TRUE)

為了從 R 中的變量構建正則表達式,在當前場景中,您可以簡單地使用paste0字符串文字與您的變量連接paste0

grep(paste0('\\{', n, '} number'), homicides, value=TRUE)

請注意, {[...]括號表達式(也稱為字符類)之外的特殊字符,如果您需要查找文字{ char.

如果您使用項目列表作為替代列表,您可以使用paste / paste0組合

words <- c('bananas', 'mangoes', 'plums')
regex <- paste0('Ben likes (', paste(words, collapse='|'), ')\\.')

由此產生的Ben likes (bananas|mangoes|plums)\\. 正則表達式匹配Ben likes bananas. Ben likes mangoes. 或者Ben likes plums. . 請參閱[R演示正則表達式演示

注意:PCRE(當您將perl=TRUE傳遞給 base R regex 函數時)或 ICU( stringr / stringi regex 函數)已證明可以更好地處理這些情況,建議使用這些引擎而不是 base 中使用的默認 TRE regex 庫R 正則表達式函數。

通常,您會希望構建一個包含應該完全匹配的單詞列表的模式,作為整個單詞。 在這里,很大程度上取決於邊界的類型以及單詞是否可以包含特殊的正則表達式元字符,它們是否可以包含空格。

在最一般的情況下,單詞邊界 ( \\b )效果很好。

regex <- paste0('\\b(', paste(words, collapse='|'), ')\\b')
unlist(regmatches(examples, gregexpr(regex, examples, perl=TRUE)))
## => [1] "bananas" "mangoes" "plums"  

\\b(bananas|mangoes|plums)\\b模式將匹配bananas ,但不會匹配banana (參見R 演示)。

如果您的列表是像

words <- c('cm+km', 'uname\\vname')

您必須首先對單詞進行轉義,即在每個元字符之前附加\\

regex.escape <- function(string) {
  gsub("([][{}()+*^$|\\\\?.])", "\\\\\\1", string)
}
examples <- c('Text: cm+km, and some uname\\vname?')
words <- c('cm+km', 'uname\\vname')
regex <- paste0('\\b(', paste(regex.escape(words), collapse='|'), ')\\b')
cat( unlist(regmatches(examples, gregexpr(regex, examples, perl=TRUE))) )
## => cm+km uname\vname 

如果您的單詞可以以特殊的正則表達式元字符開頭或結尾,則\\b單詞邊界將不起作用。 采用

  • 明確的詞邊界(?<!\\w) / (?!\\w) ,當在非單詞字符或字符串的開始/結束之間預期匹配時
  • 空白邊界(?<!\\S) / (?!\\S) ,當匹配需要用空白字符或字符串的開頭/結尾括起來時
  • 使用后視/前瞻組合和自定義字符類/括號表達式,甚至更復雜的模式構建您自己的。

R 中前兩種方法的示例(替換為用<<>>括起來的匹配項):

regex.escape <- function(string) {
  gsub("([][{}()+*^$|\\\\?.])", "\\\\\\1", string)
}
examples <- 'Text: cm+km, +km and C++,Delphi,C++CLI and C++/CLI.'
words <- c('+km', 'C++')
# Unambiguous word boundaries
regex <- paste0('(?<!\\w)(', paste(regex.escape(words), collapse='|'), ')(?!\\w)')
gsub(regex, "<<\\1>>", examples, perl=TRUE)
# => [1] "Text: cm+km, <<+km>> and <<C++>>,Delphi,C++CLI and <<C++>>/CLI."
# Whitespace boundaries
regex <- paste0('(?<!\\S)(', paste(regex.escape(words), collapse='|'), ')(?!\\S)')
gsub(regex, "<<\\1>>", examples, perl=TRUE)
# => [1] "Text: cm+km, <<+km>> and C++,Delphi,C++CLI and C++/CLI."

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM