【问题标题】:splitting a string with regex in R在R中用正则表达式拆分字符串
【发布时间】:2021-10-13 10:23:48
【问题描述】:

我正在尝试根据特定模式拆分字符串。我有数据嵌套在大括号中。我想要做的是在双花括号处拆分字符串。我已经想出了如何在数据框中使用“分离”来做到这一点,但为了将来参考,我很想知道为什么这不起作用。

我在下面提供了一个关于单个字符串的示例:

pattern_test<-"[^\\}{2,2}]*\\}{2,2}"
teststring <- "{the {dog} is {hot}},{the {cat} is {lazy}}"
tmp<-unlist(str_extract_all(teststring, pattern_test))
tmp

tmp 计算结果为 ("hot}}", "lazy}}")。

换句话说,我在“pattern_test”中尝试做的是定义一个包含所有不完全是“}}”的字符的类:[^\\}{2,2}],并在该类中找到尽可能多的字符:* ,后跟“}}”(方括号外:\\}{2,2})。我怀疑我犯了一个基本错误,但我在网上找到的大多数示例都没有帮助我弄清楚错误是什么。我想要 tmp 评估的是:

("{the {dog} is {hot}}", ",{the {cat} is {lazy}}")。为什么子串在左括号处被截断?

【问题讨论】:

  • 你为什么不能简单地在,拆分?
  • 我无法回答你的问题,但我会尝试像"\\{.*?\\}{2}" 这样的模式。
  • 感谢@MartinGal,您的解决方案有效。为了回答您的问题,我创建了一个更简单的示例,其中拆分“,”会起作用。它不适用于我的真实数据。您介意向我解释一下您的模式在做什么吗?
  • 这事会查找{,然后是}},并提取其间的所有内容。 .*? 是“非贪婪的”,所以它不会尽可能多地占用。如果没有?,这将返回整个字符串,因为最后一个字符也是}}。不是一个很好的解释,但我希望这个想法很清楚。
  • 考虑接受 Wiktor Stribiżew 的回答。

标签: r regex


【解决方案1】:

问题是你不能匹配任何文本,只能将某个多字符子字符串与否定字符类匹配,因为字符类旨在将 single 个字符匹配为单独的字符,而不是 sequences 个字符。

另一个问题是您正在尝试匹配递归模式,而 stringr / stringi 包正在使用不支持正则表达式中的递归的 ICU 正则表达式库。

为了匹配你想要的,你只能使用带有 R 的 PCRE 正则表达式库:

pattern_test<-"\\{(?:[^{}]++|(?R))*}"
teststring <- "{the {dog} is {hot}},{the {cat} is {lazy}}"
unlist(regmatches(teststring, gregexpr(pattern_test, teststring, perl=TRUE)))
## => [1] "{the {dog} is {hot}}"  "{the {cat} is {lazy}}"

请参阅R demo online。那就是:

  • \{ - 匹配 {
  • (?:[^{}]++|(?R))* - 除了{} 或整个正则表达式模式(递归)之外,一个或多个字符出现零次或多次
  • } - } 字符。

【讨论】:

  • 我学到了一些新东西,从未听说过 PCRE 或 ICU,我仍在为您的代码苦苦挣扎。但是您说,唯一的方法是使用 PCRE 正则表达式库。但是(至少在示例中)str_extract_all(teststring, "\\{.*?\\}{2}") 确实返回了预期的结果。这只是巧合吗?或者这种模式有什么缺陷?
  • @MartinGal 您的正则表达式匹配{,然后尽可能少的除换行符之外的任何零个或多个字符,直到最左边的}} 子字符串。它将匹配{aaa{...}....}....}....}}。如果你需要这个,很好。
  • 啊,我明白了!谢谢!
  • 谢谢你们。我需要消化这个,但我感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-12-14
  • 1970-01-01
相关资源
最近更新 更多