2017-07-21 108 views
1

我正在處理一個看似簡單的問題,但似乎是一個惱人的正則表達式計算。在R/Shiny中搜索引擎風格的格式字符串

我正在設計一個閃亮的應用程序,它允許用戶搜索數據庫中的字符串並計算字符串匹配的數量。

從stringr包,我最終的調用是:

str_count(text, pattern=REGEX(user_input)) 

我的目標是將用戶輸入轉換成合適的正則表達式 - 同時允許用戶輸入標準的搜索項格式的數據。

所以以下用戶輸入:

artist picasso "picasso painting" france 

應當形成以下正則表達式:

artist|picasso|picasso painting|france 

,其中溶液知道治療「畢加索的畫」作爲一個詞,由於報價。

任何幫助表示讚賞!

+0

請顯示您到目前爲止的代碼。目前,您正在進行的任務的方方面面都不清楚:1)用戶輸入的要求是什麼?它應該只是用空白分隔的條目與雙引號內的單詞代表一個項目?2)這只是純文本或正則表達式模式? 3)會不會有字詞? 4)你打算收集比賽,還是隻計算髮生的事件?這很重要,因爲這裏的'pic | pic'與'pic here'不匹配。 –

+0

謝謝你Wiktor。目前我的代碼非常稀少,只需從Shiny的textInput函數中正確解析輸入到str_count()即可。根據你的問題:1.是的。這只是用雙引號內的單詞表示的空格分隔的條目。是的,我需要非字詞。 3.現在我不收集比賽,我只是在數它們。再次感謝。 – jsl2

+0

請在下面檢查我的答案。 –

回答

2

這裏是一個基礎R溶液:

regex.escape <- function(string) { 
    gsub("([][{}()+*^${|\\\\?])", "\\\\\\1", string) 
} 

sort.by.length.desc <- function (v) v[order(-nchar(v)) ] 

s <- "artist picasso \"picasso (painting)\" france zoo" 
keys <- c(t(read.table(text=s, header=FALSE)))   # Read in the values 
keys <- sort.by.length.desc(keys)      # Sort the values 
pattern = paste(regex.escape(keys), collapse="|")  # Create the pattern 
## Test 
## cat(pattern, sep="\n")        # This shows the regex pattern 
txt <- "The artist was born in france and named picasso picasso (painting)" 
length(unlist(gregexpr(pattern, txt)))     # Count the number of occurrences 
[1] 4 

R demo。有4個匹配,因此輸出是4

詳細

  • regex.escape函數轉義,一個正則表達式引擎可以將其解釋爲特殊字符
  • sort.by.length.desc訂單的特徵向量由特徵向量長度的項目在一個下降的最重要的字符order
  • c(t(read.table(text=s, header=FALSE)))讀取用戶輸入並作爲字符向量存儲在keys
  • pattern = paste(regex.escape(keys), collapse="|")創建具有交替運營商的圖案(模樣picasso \(painting\)|picasso|artist|france|zoocat(pattern, sep="\n")顯示得到的圖案作爲一個文本字符串)
  • length(unlist(gregexpr(pattern, txt)))線計數使用基礎R gregexpr函數匹配的發生。
0

使用"[^"]*"|\S+進行全局匹配將其分開。
盲目刪除前後雙引號^"|"$
將匹配推入數組中。
將數組排序最長(降序?)。
\\$1替換每個元素的元字符([\[$^()*+|{}-\\])
最後,將元素連同|一起加入。