【问题标题】:stringr, str_extract: how to do positive lookbehind?stringr,str_extract:如何进行积极的后视?
【发布时间】:2016-03-04 19:21:07
【问题描述】:

很简单的问题。我只需要使用正则表达式肯定的lookbehind 来捕获一些字符串,但我看不到这样做的方法。

这是一个例子,假设我有一些字符串:

library(stringr)
myStrings <- c("MFG: acme", "something else", "MFG: initech")

我想提取前缀为“MFG:”的单词

> result_1  <- str_extract(myStrings,"MFG\\s*:\\s*\\w+")
>
> result_1
[1] "MFG: acme"    NA             "MFG: initech"

几乎做到了,但我不想包括“MFG:”部分,所以这就是“积极的后视”的目的:

> result_2  <- str_extract(myStrings,"(?<=MFG\\s*:\\s*)\\w+")
Error in stri_extract_first_regex(string, pattern, opts_regex = attr(pattern,  : 
  Look-Behind pattern matches must have a bounded maximum length. (U_REGEX_LOOK_BEHIND_LIMIT)
> 

它抱怨需要“有界的最大长度”,但我看不出在哪里指定。我如何使积极的后视工作?确切地说,我可以在哪里指定这个“有界最大长度”?

【问题讨论】:

  • 啊哈! Stringr 的正则表达式需要对后向进行限制!
  • 大多数情况下(Wiktor 在下面的答案中列出的除外)环视是固定宽度的,因此您不能使用量词。

标签: regex r lookbehind stringr


【解决方案1】:

您需要使用str_match,因为“lookbehind”的模式是文字,而您只是不知道空格的数量:

> result_1  <- str_match(myStrings,"MFG\\s*:\\s*(\\w+)")
> result_1[,2]
##[1] "acme"    NA        "initech"

您需要的结果将在第二列中。

注意 str_extract 不能在此处使用,因为该函数会删除捕获的值。

还有一个好处:向后看不是 infinite-width,而是 ICU 正则表达式中的 constrained-width。因此,这也将起作用:

> result_1  <- str_extract(myStrings,"(?<=MFG\\s{0,100}:\\s{0,100})\\w+")
> result_1
[1] "acme"    NA        "initech"

【讨论】:

  • 我现在明白了,谢谢!如果我不能限制后视的大小,这就是我需要做的。
  • 哇,我不知道你可以在{} in stringr 正则表达式中量化环视;真令人兴奋。但是,这将在 base 或 perl = TRUE 正则表达式中失败。
  • 这就是为什么它被称为约束宽度lookbehind:如果可以计算长度(并且可以使用具有最小值和最大值的限制量词),则可以使用它。
【解决方案2】:

我们可以使用正则表达式环视。回溯只需要完全匹配。

str_extract(myStrings, "(?<=MFG:\\s)\\w+")
#[1] "acme"    NA        "initech"

【讨论】:

  • 谢谢!是的,我的正则表达式在 .NET 中工作过,但是 R 的正则表达式有点不同!现在 \\s* 是问题所在是有道理的。
  • 没有通用的 R 正则表达式,不同的模块使用不同的风格。有 TRE、PCRE 和 ICU 正则表达式。
  • @WiktorStribiżew,不幸的是,我无法全部了解。只需要动起来,直到某些东西停止工作。
【解决方案3】:

我使用lookbehind在python中编写了代码。如果解析器找到 MFG: 那么它将抓取下一个单词

txt="MFG: acme, something else, MFG: initech"
pattern=r"(?<=MFG\:)\s+\w+"
matches=re.findall(pattern,txt)
for match in matches:
   print(match)

输出:

 acme
 initech

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多