问题 R中的正则表达式具有负后观


所以我有以下数据,比方说叫“my_data”:

Storm.Type
TYPHOON
SEVERE STORM
TROPICAL STORM
SNOWSTORM AND HIGH WINDS

我想要的是分类my_data $ Storm.Type中的每个元素是否是风暴,但我不想将热带风暴包括为暴风雨(我要将它们分开归类),这样我就可以了

Storm.Type                    Is.Storm
TYPHOON                       0
SEVERE STORM                  1
TROPICAL STORM                0
SNOWSTORM AND HIGH WINDS      1

我写了以下代码:

my_data$Is.Storm  <-  my_data[grep("(?<!TROPICAL) (?i)STORM"), "Storm.Type"]

但这只会让“严重暴风雨”成为一场风暴(但不会让SNOWSTORM和HIGH WINDS失效)。谢谢!


5472
2017-11-22 20:33


起源

有什么意义呢 (?i) 在你的正则表达式?问题是你正在寻找字符串 " STORM" 有前面的空间,所以 "SNOWSTORM" 没有资格。 - Blue Magister
嗨蓝。虽然我接受了Ben的答案,但你实际上已经解决了我的代码问题的核心问题。我想制作我的代码,以便它不关心那个空间(所以如果STORM在THUNDERSTORM或SNOWSTORM中,我想要它和STORM本身一样)。你知道我怎么摆脱我的代码正在寻找的那个空间吗? (?i)的重点是有人以“风暴”或“风暴”或“sToRm”等形式进入STORM。 - Jonathan Ross Charlton


答案:


问题是你正在寻找字符串 " STORM" 有前面的空间,所以 "SNOWSTORM" 没有资格。

作为修复,考虑将空间移动到负面的lookbehind断言中,如下所示:

ss <- c("TYPHOON","SEVERE STORM","TROPICAL STORM","SNOWSTORM AND HIGH WINDS",
        "THUNDERSTORM")
grep("(?<!TROPICAL )(?i)STORM", ss, perl = TRUE)
# [1] 2 4 5
grepl("(?<!TROPICAL )(?i)STORM", ss, perl = TRUE)
# [1] FALSE  TRUE FALSE  TRUE  TRUE

我不知道 (?i) 和 (?-i) 设置是否在正则表达式中忽略大小写。很酷的发现。另一种方法是 ignore.case 旗:

grepl("(?<!tropical )storm", ss, perl = TRUE, ignore.case = TRUE)
# [1] FALSE  TRUE FALSE  TRUE  TRUE

然后定义您的列:

my_data$Is.Storm  <-  grepl("(?<!tropical )storm", my_data$Storm.Type,
                            perl = TRUE, ignore.case = TRUE)

8
2017-11-22 21:05



真棒!!!!!!!!!! - Jonathan Ross Charlton
别客气。谢谢你教我 (?i)。我习惯使用 ignore.case 争论,但是 (?i) 对于一般的PCRE表达式更灵活。 - Blue Magister


我也不擅长正则表达式,但出了什么问题

ss <- c("TYPHOON","SEVERE STORM","TROPICAL STORM","SNOWSTORM AND HIGH WINDS")
grepl("STORM",ss) & !grepl("TROPICAL STORM",ss)
## [1] FALSE  TRUE FALSE  TRUE

......?


3
2017-11-22 20:41



谢谢!这肯定有效。 - Jonathan Ross Charlton


就像是

x <- my_data$Storm.Type
grep("STORM", x)[!grep("STORM", x)%in%grep("TROPICAL", x)]

0
2017-11-22 20:40