r - 仅在顶层拆分带有嵌套括号的字符串,其中 "level"由括号确定

标签 r regex string recursion pcre

我正在尝试创建一个正则表达式,它允许我仅在中央逗号处拆分下面的字符串。

str_1 <- "N(0, 1)"
str_2 <- "N(N(0.1, 1), 1)"
str_3 <- "N(U(0, 1), 1)"
str_4 <- "N(0, T(0, 1))"
str_5 <- "N(N(0, 1), N(0, 1))"

将它们视为分布的参数。现在,我想拆分“顶级”的逗号。

一些细节:数字可以是十进制数,可以是正数也可以是负数。它们将始终在 U()N()LN()T() 中分组并以逗号分隔。稍后将添加更多分组,因此需要更通用的解决方案或易于扩展。我要做的是在“顶级”逗号处拆分表达式。​​

现在,str_1 的第一个案例直接使用:

unlist(strsplit(str_1, ",", perl = TRUE))

在我继续之前,我需要知道我是否有嵌套。我知道如果有嵌套,我将拥有不止一个 N、U、LN 或 T。所以为了检查,我做了(对于 str_2):

length(attr(gregexpr("(N|LN|U|T)", str_2, perl = TRUE)[[1]], "match.length")) > 1

确定我是否有嵌套(这可能是一种更简洁的测试方法?)后,我可以继续计算剩余字符串的拆分。但是,这就是我被困的地方。鉴于我无法计算逗号,因为情况 str_2str_3str_4 会产生歧义。我如何确保只在中央逗号处拆分?

我希望得到以下输出(因此去掉第一个字母和括号以及最后一个括号)

# str_2
"N(0.1, 1)" "1"

# str_3
"U(0, 1)" "1"

# str_4
"0" "T(0, 1)"

# str_5
"N(0, 1)" "N(0, 1)"

如果可能的话,我想继续使用 base R 来减少代码的依赖数量。任何帮助深表感谢。这也可能无法通过正则表达式解决,但需要一种可能通过递归的编程方法,如 this 中的建议Java问题。

最佳答案

如果您的字符向量采用您显示的格式,您可以使用单个 PCRE 正则表达式实现所需的内容:

(?:\G(?!^)\s*,\s*|^N\()\K(?:\d+|\w+(\([^()]*(?:(?1)[^()]*)*\)))(?=\s*,|\)$)

参见 regex demo . 详情

  • (?:\G(?!^)\s*,\s*|^N\() - 上一次成功匹配的结尾 (\G(?!^ )) 然后是用零个或多个空白字符括起来的逗号 (\s*,\s*) 或 N( 开头的字符串字符串 (^N\()
  • \K - 一个匹配重置运算符,它丢弃目前匹配内存缓冲区中所有匹配的文本
  • (?: - 非捕获组的开始
    • \d+ - 一个或多个数字
    • | - 或者
    • \w+ - 一个或多个单词字符
    • (\([^()]*(?:(?1)[^()]*)*\)) - 第 1 组(需要递归才能正常工作):a (,然后是 () 以外的任何零个或多个字符,然后是第 1 组模式的零个或多个出现(递归)和然后是 () 以外的零个或多个字符,然后是 ) 字符
  • ) - 非捕获组结束
  • (?=\s*,|\)$) - 字符串末尾紧跟零个或多个空格,然后是逗号或 ) 字符。

参见 regex demo :

strs <- c("N(0, 1)", "N(N(0.1, 1), 1)", "N(U(0, 1), 1)", "N(0, T(0, 1))", "N(N(0, 1), N(0, 1))")
p <- "(?:\\G(?!^)\\s*,\\s*|^N\\()\\K(?:\\d+|\\w+(\\([^()]*(?:(?1)[^()]*)*\\)))(?=\\s*,|\\)$)"
regmatches(strs, gregexpr(p, strs, perl=TRUE))
# => [[1]]
#    [1] "0" "1"
#    
#    [[2]]
#    [1] "N(0.1, 1)" "1"        
#    
#    [[3]]
#    [1] "U(0, 1)" "1"      
#    
#    [[4]]
#    [1] "0"       "T(0, 1)"
#    
#    [[5]]
#    [1] "N(0, 1)" "N(0, 1)"

关于r - 仅在顶层拆分带有嵌套括号的字符串,其中 "level"由括号确定,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/65235254/

相关文章:

string - 我可以访问从 Delphi CreateProcess 命令返回的字符串吗?

r - 如何删除 R Markdown 生成的 HTML 文件左侧的 "padding"

r - 带有子组的组的反向引用编号

r - 自动 - "Convert numbers stored as text to numbers"

regex - vi:::s 如何只替换一行中的第二次出现?

java - 捕获组 REGEX Java

java - 空字符串对象和字符串文字的串联

java - 如何在 Java 中对空字符串应用 toUpperCase()?

R : How evaluate formals (arguments) of function?

R:基于嵌套循环生成新列