调和正则表达式的行为

3

我在这里尝试使用正则表达式 ((?:I\d-?)*I3(?:-?I\d)*) 参考链接

从字符串 A-B-C-I1-I2-D-E-F-I1-I3-D-D-D-D-I1-I1-I3-I1-I1-I3-I2-L-K-I3-P-F-I2-I2 中,我得到以下匹配结果:I1-I3I1-I1-I3-I1-I1-I3-I2I3,这是期望的行为。然而,在R中:

x <- "A-B-C-I1-I2-D-E-F-I1-I3-D-D-D-D-I1-I1-I3-I1-I1-I3-I2-L-K-I3-P-F-I2-I2"
strsplit(x, "(?:I\d-?)*I3(?:-?I\d)*")

这会返回一个错误:
Error: '\d' is an unrecognized escape in character string starting ""(?:I\d"

我尝试过使用perl=TRUE,但没有任何区别。
我还尝试修改正则表达式为:(?:I\\d-?)*I3(?:-?I\\d)*,但它并没有给出正确的结果,相反它匹配了A-B-C-I1-I2-D-E-F--D-D-D-D--L-K--P-F-I2-I2。 如何在R中复制所需行为?

1
尝试使用\\d进行转义,例如strsplit(x, "(?:I\\d-?)*I3(?:-?I\\d)*") - akrun
@akrun:这并没有得到期望的结果 - 请参见更新的问题。 - histelheim
我在尝试修复错误,所以没有检查期望的结果。 - akrun
@akrun:问题是:“我如何在R中复制所需的行为?” - histelheim
1
str_extract_all(x, '(?:I\\d-?)*I3(?:-?I\\d)*') 我只看了错误部分。抱歉。 - akrun
1个回答

1
如果我们需要根据所显示的模式split字符串并获取子字符串,则可以将其作为要跳过的模式 ((*SKIP)(*F)),并使用其余字符拆分字符串。
 v1 <- strsplit(x, '(?:I\\d-?)*I3(?:-?I\\d)*(*SKIP)(*F)|.', perl=TRUE)[[1]]

空元素可以使用nzchar来移除,它会返回一个逻辑向量TRUE/FALSE,取决于字符串是否为空或者非空。
 v1[nzchar(v1)]
 #[1] "I1-I3"                "I1-I1-I3-I1-I1-I3-I2" "I3"   

如果我们更关心提取模式,str_extract会很有用。

 library(stringr)
 str_extract_all(x, '(?:I\\d-?)*I3(?:-?I\\d)*')[[1]]
 #[1] "I1-I3"                "I1-I1-I3-I1-I1-I3-I2" "I3"  

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接