用于匹配所有逗号的正则表达式,除非它们包含在圆括号或中括号之间

问题描述 投票:0回答:3

考虑 R 中的以下代码:

x <- "A, B (C, D, E), F, G [H, I, J], K (L (M, N), O), P (Q (R, S (T, U)))"
strsplit(x, split = "some regex here")

我希望它返回类似于包含字符向量的列表的内容

"A"
"B (C, D, E)"
"F"
"G [H, I, J]"
"K (L (M, N), O)"
"P (Q (R, S (T, U)))"

编辑:提议的替代问题不能回答我的问题,因为允许嵌套括号和方括号,并且有可能发生 n 级嵌套(超过 2)。

r string strsplit
3个回答
2
投票

这看起来更像是自定义解析器的工作,而不是单个正则表达式。我很想被证明是错的,但是在我们等待的时候,这里有一个非常简单的解析函数可以完成工作。

parse_nested <- function(string) {
  
  chars <- strsplit(string, "")[[1]]
  
  parentheses <- numeric(length(chars))
  parentheses[chars == "("] <- 1
  parentheses[chars == ")"] <- -1
  parentheses <- cumsum(parentheses)

  brackets <- numeric(length(chars))
  brackets[chars == "["] <- 1
  brackets[chars == "]"] <- -1
  brackets <- cumsum(brackets)
  
  split_on <- which(brackets == 0 & parentheses == 0 & chars == ",")
  split_on <- c(0, split_on, length(chars) + 1)
  
  result <- character()
  
  for(i in seq_along(head(split_on, -1))) {
    x <- paste0(chars[(split_on[i] + 1):(split_on[i + 1] - 1)], collapse = "")
    result <- c(result, x)
  }
  
  trimws(result)
}

产生:

parse_nested(x)
#> [1] "A"                   "B (C, D, E)"         "F"                  
#> [4] "G [H, I, J]"         "K (L (M, N), O)"     "P (Q (R, S (T, U)))"

0
投票

仅使用

regex
。由于
stringr
不允许递归,因此我们需要使用基 R。

x <- "A, B (C, D, E), F, G [H, I, J], K (L (M, N), O), P (Q (R, S (T, U)))"

regmatches(x, 
  gregexpr("([A-Z] )*([\\(\\[](?>[^()\\[\\]]|(?R))*[\\)\\]])|[A-Z]", 
            x, perl = TRUE))

#> [[1]]
#> [1] "A"                   "B (C, D, E)"         "F"                  
#> [4] "G [H, I, J]"         "K (L (M, N), O)"     "P (Q (R, S (T, U)))"

0
投票

这使用了

R 表达式中的求和项
中的 getTerms 而不是正则表达式。这个函数相当短,只有 3 行主体。

假设没有加号将每个逗号转换为加号,转换为 一个语言对象,然后使用

getTerms
将其分解为单独的术语。最后将每个术语格式化为字符串并将加号转换回逗号。

x |>
  chartr(",", "+", x = _) |>
  str2lang() |>
  getTerms() |>
  sapply(\(x) chartr("+", ",", format(x)))

给予

[1] "A"                  "B(C , D , E)"       "F"                 
[4] "G[H , I , J]"       "K(L(M , N) , O)"    "P(Q(R , S(T , U)))"

注意

问题中的输入

x
就是这个字符串

x <- "A, B (C, D, E), F, G [H, I, J], K (L (M, N), O), P (Q (R, S (T, U)))"
© www.soinside.com 2019 - 2024. All rights reserved.