【问题标题】:R regex help: Perl s modifier + lookahead too aggressiveR 正则表达式帮助:Perl 的修饰符 + 前瞻过于激进
【发布时间】:2015-10-28 12:52:55
【问题描述】:

我正在尝试使用 R 的 gsub("regexp", "", string, perl=T) 删除两个给定子字符串之间的所有字符(包括换行符)(即用空字符串替换所有匹配项)。

到目前为止,我所拥有的是正则表达式(?<=A)(?s:.)+(?=B),其中我使用s 修饰符使. 也匹配换行符。问题是当前瞻B 多次出现时,我只想删除A 和第一个B 之间的任何内容:

我有A remove \r\n this B but leave this B

我想要AB but leave this B

但到目前为止我得到的是AB

如何修改正则表达式以使先行在第一次出现时停止?

【问题讨论】:

  • 在 Perl 中,A\KB(?=C)(?<=A)B(?=C) 快。 PCRE 可能也是如此。

标签: regex r pcre


【解决方案1】:

让它不贪心试试这个:

(?<=A)(?s:.)+?(?=B)

【讨论】:

  • 完美,谢谢!抱歉这个愚蠢的问题(事后看来),我做了很多谷歌搜索,但不知道“贪婪”这个词,所以从来没有找到答案。
  • 在这里学习并保持明智stackoverflow.com/questions/5319840/…
  • 可选的量词*没用,应该是非可选的。
  • 使用非贪婪修饰符作为优化是脆弱的。我认为如果你只在模式中使用一个是安全的,但就是这样。由于在这种情况下避免这种危险的结构更容易也更清楚,我不同意这种解决方案。
  • 在这种情况下,最好写成(?s:.*?)(?s:.+?)。无需重新调整单个字符的范围。
【解决方案2】:

这是使用Dot-All、点和量词的特殊情况
不被使用。对它的阅读令人困惑,并没有传达其真正意图。

(?&lt;=A)[^B]+(?=B)

【讨论】:

  • 这在我给出的示例案例中确实可以完美运行。如果我想提前查看 \\\\centering 怎么办? (我正在使用这个正则表达式来清理一些遗留的 LaTeX 文件)
  • @user28400 - 使用.*.*? 充满危险,有一些方法可以不有效地使用它,但就像填充物一样危险。例如,在复合子表达式中,.*? 可以解释为贪婪,并且无法按照您的想法行事。
  • (?:(?!STRING).)(?:STRING),因为 [^CHAR]CHAR。 (假定为s 修饰符)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多