如何只删除单括号并保留成对的

Ano*_*n R 5 regex r

亲爱的老师们/各位 R 用户,大家好,

我最近开始认真学习正则表达式,最近我遇到了一个案例,我们只想保留成对的括号()并省略未配对的括号。这是我的示例数据:

structure(list(t1 = c("Book (Pg 1)", "(Website) Online)", "Journal: 2018)", 
"Book1 (pg 2) book 3 (pg4)  something)")), class = "data.frame", row.names = c(NA, 
-4L))
Run Code Online (Sandbox Code Playgroud)

我想要的输出是这样的:

structure(list(t1 = c("Book (Pg 1)", "(Website) Online", "Journal: 2018", 
"Book1 (pg 2) book 3 (pg4)  something")), class = "data.frame", row.names = c(NA, 
-4L))
Run Code Online (Sandbox Code Playgroud)

我自己已经设法用下面的代码来做到这一点,但我认为肯定有一种更有效的方法来解决它。事实上,我想学习其他获得类似结果的方法:

test$t2 <- gsub("([(]?.*[)]?\\s+[^(]\\w+)[)]|([(].*[)])", "\\1\\2", test$t1)
test

                                     t1                                   t2
1                           Book (Pg 1)                          Book (Pg 1)
2                     (Website) Online)                     (Website) Online
3                        Journal: 2018)                        Journal: 2018
4 Book1 (pg 2) book 3 (pg4)  something) Book1 (pg 2) book 3 (pg4)  something
Run Code Online (Sandbox Code Playgroud)

我正则表达式的另一个问题是,当我换的地方RHS和LHS的|它不会导致预期的结果,我很好奇为什么。如果您能就解决此类问题给出一些解释,我将不胜感激。

非常感谢您提前。

Wik*_*żew 3

您可以使用

\n
> gsub("\\\\([^()]*\\\\)(*SKIP)(*F)|[()]", "", df$t1, perl=TRUE)\n[1] "Book (Pg 1)"                          "(Website) Online"                    \n[3] "Journal: 2018"                        "Book1 (pg 2) book 3 (pg4)  something"\n
Run Code Online (Sandbox Code Playgroud)\n

请参阅R 在线演示和正则表达式演示。

\n

细节

\n
    \n
  • \\([^()]*\\)(*SKIP)(*F)- ,除 and(之外的零个或多个字符,然后是一个字符,并且此匹配文本将被丢弃,并从失败位置开始搜索下一个匹配项())
  • \n
  • |- 或者
  • \n
  • [()]- 匹配 a(或)字符。
  • \n
\n

如果您需要跳过平衡的嵌套括号,您可以使用

\n
gsub("(\\\\((?:[^()]++|(?-1))*\\\\))(*SKIP)(*F)|[()]", "", df$t1, perl=TRUE)\n
Run Code Online (Sandbox Code Playgroud)\n

在这里,匹配并跳过嵌套括号(如)(\\((?:[^()]++|(?-1))*\\))(*SKIP)(*F)之间的任何子字符串,并匹配其他上下文中的任何and 。(aa (bb(c)x)x)|[()]()

\n

请参阅此正则表达式演示。

\n

和(= ) PCRE 动词(*SKIP)的意思是:(*F)(*FAIL)

\n
    \n
  • (*SKIP)- 引擎前进到与模式中(*SKIP)遇到的位置相对应的字符串位置,并在该位置开始新的匹配尝试,或者引擎跳到与匹配的位置相对应的字符串位置(*SKIP)\xe2\x80\x94可能会保存多次无果的比赛尝试
  • \n
  • (*F)- 向正则表达式引擎发出失败信号,触发回溯(如果适用)(此处,由于交替运算符而导致|)。请注意,(*F)与 相同(?!),即如果右侧有任何内容,则失败。
  • \n
\n