R separate_wider_regex是否允许使用多行正则表达式标志(?m)或regex(...,multiline=TRUE)?

jv4diomz  于 2023-06-27  发布在  其他
关注(0)|答案(1)|浏览(77)

我正在尝试用tidyr::separate_wider_regex替换已弃用的tidyr::extract。然而,我正在分隔一个多行文本列,似乎separate_wide_regex不遵守多行regex标志(?m)或相关的regex(...,multiline=TRUE)函数。
MWE:

tibble(x = 'a\nmultiline\ntext') %>% 
separate_wider_regex(x, c('(?m).*?', m='(?m)multiline', '(?m).*'))

separate_wider_regex()中的错误:期望x的每个值都匹配模式、整个模式以及仅匹配模式。% 1值有问题。使用too_few = "debug"诊断问题。使用too_few = "start"使此消息静音。运行rlang::last_trace()查看错误发生的位置。
相反,

str_match('a\nmultiline\ntext', '(?m)multiline')

产生预期的

[,1]       
[1,] "multiline"

谢谢你的帮助!
我也试过玩添加/删除(?m)标志,替换为正则表达式(...,multiline=TRUE)等。

odopli94

odopli941#

separate_wider_regex()statespatterns参数的文档:

  • 图案 *

一个命名的字符向量,其中的名称为列名,值为与向量内容匹配的正则表达式。未命名的组件将匹配,但不包括在输出中。
它可能 * 应该 * 说的是:
[...]这些值是匹配vector的整个内容的正则表达式。
该函数将^添加到模式的开头,并将$添加到模式的结尾,这意味着它要么 * 全部 * 匹配,要么 * 全部 * 不匹配。
为什么你发布的正则表达式不起作用的简短版本是因为点字符不匹配换行符。
长版本是,好吧,为了帮助我解释,这里是你的代码的工作版本:

tibble(x = "a\nmultiline\ntext") %>%
  separate_wider_regex(x, c(a = "(?m).*?", "\n", b='(?m)multiline', "\n", c='(?m).*'), too_few = "debug")

# a     b         c     x                    x_ok  x_matches x_remainder
#  <chr> <chr>     <chr> <chr>                <lgl>     <int> <chr>      
# 1 a     multiline text  "a\nmultiline\ntext" TRUE          5 ""

?m所做的一切使您能够使用^$分别查找行的开始和结束。换句话说,您可以将b='(?m)multiline'替换为b='(?m)^.*$'b='multiline',它将返回相同的内容。
要匹配 * 跨 * 个换行符(即要使.也匹配换行符),请使用(?s)

# this is maybe what you had in mind:

tibble(x = "a\nmultiline\ntext") %>%
  separate_wider_regex(x, c(a = "(?s).*?",b='multiline', c='(?s).*'), too_few = "debug")

# A tibble: 1 × 7
#  a     b         c        x                    x_ok  x_matches x_remainder
#  <chr> <chr>     <chr>    <chr>                <lgl>     <int> <chr>      
# 1 "a\n" multiline "\ntext" "a\nmultiline\ntext" TRUE          3 ""

最后一点:对于将来阅读这篇文章的人,如果你被这个功能难倒了:使用too_few = "debug"参数!它帮助我调试了很多,特别是当一些东西匹配部分文本,而不是整个文本时。真的是天赐之物!

相关问题