stringr:正则表达式,用于匹配和提取包含相同子字符串的字符串(包括唯一子字符串)

时间:2018-12-14 14:27:02

标签: r regex string stringr

所以我在数据框中有一个包含这样的名称的列:

colnames <- c("YouAreHappy","YouAreHappy1", "YouAreHappy2", "NiceSmiles", "NiceSmiles1", "NiceSmiles2")

我正在尝试使用stringr的{​​{1}}函数来提取名称的特定部分,例如“ Happy”,“ Happy1”,“ Happy2”,“ Smiles”, “ Smiles1”和“ Smiles2”。

我尝试将regex与`str_extract'一起使用,如下所示:

str_extract

但是我要提取:

> str_extract(colnames, regex("Happy|Happy1|Happy2|Smiles|Smiles1|Smiles2"))
[1] "Happy"  "Happy"  "Happy"  "Smiles" "Smiles" "Smiles"

我显然正在解决此错误,但是我不知道在哪里以及如何做。我知道[1] "Happy" "Happy1" "Happy2" "Smiles" "Smiles1" "Smiles2" 暗示着|,但我对正则表达式的了解还不足以规避这一障碍。我是正则表达式之类的新手(刚刚发现regular expressions 101),因此希望使用任何指针。

1 个答案:

答案 0 :(得分:2)

使用Happy|Happy1|Happy2|Smiles|Smiles1|Smiles2模式时,请记住,与“ wins”匹配的第一个备选方案和ICU regex引擎(用于 stringr )并不考虑以下备选方案。请注意,您的正则表达式中的几种替代方法可能在同一位置匹配,较短的替代方法排在较长的替代方法之前。这就是为什么结果不符合预期的原因。参见Remember That The Regex Engine Is Eager

确实,TRE regex引擎的工作原理有所不同。 regmatches(colnames, gregexpr("Happy|Happy1|Happy2|Smiles|Smiles1|Smiles2", colnames))将为您带来预期的匹配,因为它是文本导向的正则表达式引擎,是匹配时间最长的替代“ wins”。参见Text-Directed Engine Returns the Longest Match

但是,您可以只使用

"(Smiles|Happy)\\d*"
在两个引擎中

以获得相同的输出。确保备选方案在字符串中的同一位置不匹配,这是最佳做法。 (Smiles|Happy)\d*匹配SmilesHappy,然后匹配0个或多个数字。