2017-02-17 103 views
2

我想匹配的字符串:如何匹配字符串匹配[A-Z _] *,但與非重複符號 「_」

  • 由組成[A-Z_]。
  • 這不以「_」開始或結束;
  • 這不包括重複的「_」符號。

因此,例如預期的匹配結果將是:

"x"; "x_x" > TRUE 
"_x"; "x_"; "_x_"; "x__x" > FALSE 

我的問題,實現這是我可以排除結束或者以「_」,但我的正則表達式也排除了長度爲1名的字符串的字符串。

grepl("^[a-z][a-z_]*[a-z]$", my.string) 

我的第二個問題是,我不知道如何來否定匹配雙字符grepl("(_)\\1", my.string)以及如何我可以用我的正則表達式的第1部分它集成。

如果可能我想用perl = FALSE來做到這一點。

+0

什麼'_x_x'或'_x_x_'? – akrun

+0

@akrun懷疑他們在以_開頭時都失敗。但是'x_x_x'呢?你想拒絕*毗鄰*'_'或任何地方有多個字符串的任何字符串? – Spacedman

+0

他們不應該匹配,因爲他們開始或以「_」結尾 –

回答

2

您需要使用以下TRE正則表達式:

grepl("^[a-z]+(?:_[a-z]+)*$", my.string) 

regex demo

詳細

  • ^ - 串
  • 開始
  • [a-z]+ - 一個或多個ASCII字母
  • (?:_[a-z]+)* - 零個或更多個序列的
    • _*) - 下劃線
    • [a-z]+ - 一個或多個ASCII字母
  • $ - 字符串的結尾。

R demo

my.string <- c("x" ,"x_x", "x_x_x_x_x","_x", "x_", "_x_", "x__x") 
grepl("^[a-z]+(?:_[a-z]+)*$", my.string) 
## => [1] TRUE TRUE TRUE FALSE FALSE FALSE FALSE 
+1

謝謝,它完美且完全可以理解,詳細的解釋 –

+0

不客氣。如果您對目前的問題有任何疑問,請不要猶豫,留言。雖然我正在山裏度假,但我時不時地檢查一下。 –

2

這似乎是正確識別項目:

dat <- c("x" ,"x_x","_x", "x_", "_x_", "x__x") 
grep("^_|__|_$", dat, invert=TRUE) 
[1] 1 2 

所以嘗試:

!grepl("^_|__|_$", dat) 
[1] TRUE TRUE FALSE FALSE FALSE FALSE 

只是使用否定和由正則表達式的邏輯OR運算符分隔的三個條件模式「|」。

+0

如果您還想強制使用'[a-z_]'使用'!grepl(「^ _ | __ | _ $」,dat)&grepl(「^ [a-z _] + $」,dat )' – Rentrop

+0

這個解決方案也會驗證['!!@!@!@!@!''](http://ideone.com/nkC2d4)。 –

+0

@WiktorStribiżew:提問者的責任是包含一系列涵蓋「真實」用例可能性的測試用例。添加一個或者一個排除其他[:punct:]項目的條目是相當容易的。 –

1

另一個正則表達式,它使用分組(*進行計算。

myString <- c("x_", "x", "_x", "x_x_x", "x_x", "x__x") 

grepl("^([a-z]_)*[a-z]$", myString) 
[1] FALSE TRUE FALSE TRUE TRUE FALSE 

所以^([a-z]_)*匹配字符串的開頭0以上對「[A-Z] _」和[a-z]$確保了最後一個字符是小寫字母字符。

+1

這匹配不應匹配的''x __「':'grepl(」^([az] _)* [a-z _] $「,」x __「)':'TRUE' –

+1

可能你的意思是' grepl(「^([az] + _)* [az] $」,myString)' –

+1

感謝您的支持,[a-z _] $應該是[az] $ – lmo