【问题标题】:R regex: grep excluding hyphen/dash as boundaryR 正则表达式:grep 不包括连字符/破折号作为边界
【发布时间】:2015-03-24 02:13:24
【问题描述】:

我正在尝试将向量中的确切单词与可变字符串进行匹配。为此,我使用了边界。但是,我希望连字符/破折号不要被视为单词边界。这是一个例子:

vector<-c(    
"ARNT",
"ACF, ASP, ACF64",
"BID",
"KTN1, KTN",
"NCRNA00181, A1BGAS, A1BG-AS",
"KTN1-AS1")

要匹配包含“KTN1”的字符串,我正在使用:

grep("(?i)(?=.*\\bKTN1\\b)", vector, perl=T) 

但这匹配“KTN1”和“KTN1-AS1”。

有没有办法可以将破折​​号视为一个字符,以便将“KTN1-AS1”视为一个完整的单词?

【问题讨论】:

  • 根据您的需要两者都匹配。
  • 您的意思是grep("(?i).*\\bKTN1[-\\w]*\\b", vector, perl=T)grep("(?i).*\\bKTN1[-\\w]*\\b", vector, perl=T, value=T)
  • 我怎么能只匹配“KTN1”?

标签: regex r


【解决方案1】:

要匹配向量元素中的特定单词,您需要使用诸如 regmatchesstr_extract_all (来自 stringr 包)之类的函数,而不是 grep,因为 grep 只会返回找到匹配项的元素索引。

> vector<-c(    
+     "ARNT",
+     "ACF, ASP, ACF64",
+     "BID",
+     "KTN1, KTN",
+     "NCRNA00181, A1BGAS, A1BG-AS",
+     "KTN1-AS1")
> regmatches(vector, regexpr("(?i)\\bKTN1[-\\w]*\\b", vector, perl=T))
[1] "KTN1"     "KTN1-AS1"

> library(stringr)
> unlist(str_extract_all(vector[grep("(?i)\\bKTN1[-\\w]*\\b", vector)], perl("(?i).*\\bKTN1[-\\w]*\\b")))
[1] "KTN1"     "KTN1-AS1"

更新:

> grep("\\bKTN1(?=$|,)", vector, perl=T, value=T)
[1] "KTN1, KTN"

返回包含字符串KTN1 后跟逗号或行尾的元素。

> grep("\\bKTN1\\b(?!-)", vector, perl=T, value=T)
[1] "KTN1, KTN"

返回包含字符串KTN1 后面没有连字符的元素。

【讨论】:

  • 我实际上只是想要返回字符串“KTN1, KTN”。我感兴趣的是包含“KTN1”和“KTN1-AS1”的字符串应该被视为不同的单词,因此不匹配。
  • 完美!谢谢!我使用 grep 的原因是因为这个“向量”是数据框的一列,我想选择与该词匹配的行。
【解决方案2】:

我会保持简单并创建一个DIY 边界。

grep('(^|[^-\\w])KTN1([^-\\w]|$)', vector, ignore.case = TRUE)

我们使用捕获组来定义边界。我们匹配一个不是连字符或单词字符的字符——字符串的开头或结尾,这更接近\b 边界的意图。

【讨论】:

  • 谢谢!这也很有效,而且解释很有帮助!
  • 我不确定我是否可以在这里问这个问题,但是如果我也不想在单词前加上连字符怎么办?说,如果我有一个匹配的单词 A-KTN1。我尝试将 ([^-\\w]) 放在第一个 \\b 的位置,但它在那里不起作用。
  • @user4451922 试试grep("(?&lt;!-)\\bKTN1\\b(?!-)", vector, perl=T, value=T)
  • 太棒了!再次感谢您!
猜你喜欢
  • 2012-04-29
  • 2017-12-20
  • 1970-01-01
  • 2014-07-31
  • 2011-04-11
相关资源
最近更新 更多