【问题标题】:How to tell a RegEx to be greedy on an 'Or' Expression如何告诉正则表达式对“或”表达式贪婪
【发布时间】:2018-10-08 17:56:00
【问题描述】:

文字:

[A]I'm an example text [] But I want to be included [[]]
[A]I'm another text without a second part []

正则表达式:

\[A\][\s\S]*?(?:(?=\[\])|(?=\[\[\]\]))

使用上述正则表达式,无法捕获第一个文本的第二部分。

Demo

有没有办法告诉正则表达式对“或”部分贪婪?我想抓住尽可能多的群体。

编辑 1:

最初的尝试:

Demo

编辑 2:

我想要达到的目标:

在我们公司,我们使用网络服务来报告我们的工作时间。我想开发一个桌面应用程序来轻松关注工作时间。我成功下载了服务器的响应(包含所有必要的数据),但不幸的是,这个日期处于一个安静的糟糕状态,无法处理它。

因此,我需要将整个页面分成不同的日子。不幸的是,一天可能有多个时间集,例如06:05 - 10:33; 10:55 - 13:13。上面发布的正则表达式在第一次设置之后(所以在 10:33 之后)分割了天数数据集。因此,我希望正则表达式处理 Or 部分“贪婪”(如果表达式 1(较大的表达式)为真,则跳过第二个表达式。如果表达式 1 为假,则使用第二个)。

【问题讨论】:

  • 按从大到小排列 or 语句。
  • @zzxyz 我已经尝试过了,但是将正则表达式重新排序为 "[A][\s\S]*?(?:(?=[[]])|(?=[] ))" 有相同的结果
  • 啊,是的,问题不在于你的or 表达(stackoverflow.com/questions/35606426/…) 问题在于你的非贪婪引导。嗯......你还需要在你的or 中从最喜欢到最不喜欢的匹配向左->向右。

标签: c# regex regex-greedy


【解决方案1】:

我已经改变了你的正则表达式(实际上更简单)来做你想做的事:

\[A\].*\[?\[\]\]?

首先匹配“[A]”,然后匹配任意数量的任意字符(贪婪),最后匹配一两个“[]”。

编辑

这将更喜欢双方括号:

\[A\].*(?:\[\[\]\]|\[\])

【讨论】:

  • 好的,请忽略我的最后一条评论——我只是在检查结果之前写的。我不会尝试使其适应我最初的需求:)
  • 好的,好像我不小心在我的 OR 周围放置了一个非捕获组 - 因此,优先级不起作用。谢谢!
【解决方案2】:

你可以使用

\[A][\s\S]*?(?=\[A]|$)

请参阅regex demo

详情

  • \[A] - [A] 子字符串
  • [\s\S]*? - 尽可能少的任何 0+ 个字符
  • (?=\[A]|$) - 紧跟[A] 或字符串结尾的位置。

在 C# 中,您实际上甚至可以使用拆分操作:

Regex.Split(s, @"(?!^)(?=\[A])")

看到这个.NET regex demo(?!^)(?=\[A]) 正则表达式匹配字符串中的位置,该位置不在开头,并且紧随其后的是[A]

如果可以用任何字母代替A,请将A 替换为[A-Z][A-Z]+

【讨论】:

  • 当然,这适用于这个例子 - 不幸的是,我有一个用例,这种方法不起作用,因为我在前瞻中使用的字符串存在于文本本身中。分隔“整个”文本的唯一方法是使用最后几个字符([ 和 ])(它们只是长度不同)。
  • @C4p741nZ 然后显示真正的字符串。您应该能够定义模式应该在哪里开始和停止匹配。否则,您不能使用正则表达式。
  • 原始文本的长度约为 35.000 个字符 - 因为 SO 只允许 30.000 个字符,这并不容易。我会尽量减少一些不必要的线条。
  • 使用 pastebin.com,但最好只分享重现问题所需的最小文本。请在问题中添加匹配边界定义,否则,我宁愿投票结束。
  • 我在 regex101 上添加了一个包含原始数据的演示,并添加了我想要做什么的解释(如果这就是你对“匹配边界定义”的意思)。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-03
  • 2011-04-27
相关资源
最近更新 更多