R语言 匹配字符或数字后面的最后一个三重下划线

fgw7neuy  于 2023-04-18  发布在  其他
关注(0)|答案(3)|浏览(139)

我正在努力找出一个正则表达式,它可以匹配前面有字母或数字的字符串中的最后一个三重下划线。最终,我希望能够提取这个匹配之前和之后的字符。我还需要用base R来完成这个任务

x <- c("three___thenfour____1", 
             "only_three___k")

我最接近的是尝试适应Regex Last occurrence?

sub("^(.+)___(?:.(?!___))+$", "\\1", x, perl = TRUE)
[1] "three___thenfour_" "only_three"

但我真正想得到的是
c("three___thenfour", "only_three")c("_1", "k")
(The到目前为止,我获得这些结果的唯一方法是通过strsplit,但它感觉笨拙且效率低下)

do.call("rbind", 
        lapply(strsplit(x, "___"), 
               function(x){ 
                 c(paste0(head(x, -1), collapse = "___"), tail(x, 1))
               }))

     [,1]               [,2]
[1,] "three___thenfour" "_1"
[2,] "only_three"       "k"

有什么建议吗?

piok6c0g

piok6c0g1#

这符合您当前的要求:

x <- c(
  "three___thenfour____1", 
  "only_three___k",
  "test___test___test___test",
  "1_____test"
)
             
gsub("^(.*?)___(?!.*___)(.*)$", "\\1 \\2", x, perl = TRUE)

它输出:

[1]"three___thenfour _1" [2]"only_three k" [3]"test___test___test test" [4]"1 __test"

说明:

  • ^(.*?)___-在开始时非贪婪地匹配任何内容,然后将___分配到第一组
  • (?!.*___)-在此之后,不允许___前面有任何内容,负先行用于此目的
  • (.*)$-将字符串末尾之后的任何内容匹配到第二组
pkwftd7m

pkwftd7m2#

您可以使用regexpr.*[^_]___匹配从左开始计数的最后一个___-.*___将匹配从右开始计数的最后一个。使用regmatches提取第一部分,使用substring提取最后一部分。

i <- regexpr(".*[^_]___", x)
sub("___$", "", regmatches(x, i))
#[1] "three___thenfour" "only_three"

substring(x, attr(i, "match.length")+1L)
#[1] "_1" "k"
r1wp621o

r1wp621o3#

你可以试试这个

strsplit(x, '(?<!_)_{3}(?!.*(?<!_)_{3})', perl=TRUE)
# [[1]]
# [1] "three___thenfour" "_1"              
# 
# [[2]]
# [1] "only_three" "k"

最后得到向量

strsplit(x, '(?<!_)_{3}(?!.*(?<!_)_{3})', perl=TRUE) |>
  as.data.frame() |> unname() |> asplit(1)
# [[1]]
# [1] "three___thenfour" "only_three"      
# 
# [[2]]
# [1] "_1" "k"

相关问题