匹配 gsub 中的一组数字,但在前面有“/”符号时排除一组相同的数字

Matching a set of digits in gsub but excluding a set of identical digits when preceded by a "/"sign

问题

我正在使用类似于下面创建的 vecA 的向量:

vecA <- c("data2002", "valueA2002", "value2005", "indicator2008/2009",
          "something2011/12", "abc2011/14")

我想得到以下格式的 vecB

vecA <- c("data_2002", "valueA_2002", "value_2005", "indicator_2008/2009",
          "something_2011/12", "abc_2011/14")

总之,时间序列标识符前有一个下划线_,但奇怪的是后者可能被构造。时间序列标识符唯一的共同特征是它以20开头。没有其他共同特征,时间序列标识符可能是:

采取措施

我想使用匹配 20regex 模式和避免匹配 20 两次。例如在字符串中:

代码

我会从:

开始
gsub(pattern = "20", replacement = "_20",x = names(x))

但这将匹配 20 的所有实例。所以我的想法是在正则表达式 20(?<!\2) 的行上使用 look aheads/behind ,在那里我可以从匹配中排除某些东西。

我们匹配一个或多个非数字元素 (\D+),将其捕获为一组 ((..)),然后是数字正则表达式前瞻 ((?=\d)) 并替换为反向引用 (\1) 后跟 _.

sub('(\D+)(?=\d)', '\1_', vecA, perl=TRUE)
#[1] "data_2002"           "valueA_2002"         "value_2005"          "indicator_2008/2009" "something_2011/12"   "abc_2011/14"      

或者不用环顾四周,我们使用两个捕获组。我们之前提到的第一个,后面是第二个以数字开头的捕获组,然后是多个字符中的一个。在替换中,我们使用了由 _.

分隔的两个反向引用
sub('(\D+)(\d.*)', '\1_\2', vecA)

如果这需要更具体,即仅匹配以 20

开头的数字
sub('(\D+)(20.*)', '\1_\2', vecA)