【问题标题】:is there a way make a character to be part of two matches not only one有没有办法让一个角色成为两个匹配的一部分,而不仅仅是一个
【发布时间】:2021-12-05 16:22:29
【问题描述】:

我有这个正则表达式:1(0+)1

我正在测试这个值:1010010001

我希望我有三个匹配项:101100110001,但我得到的匹配项只有:10110001

第二个 1 应该是两个匹配项的一部分:1011001

有没有办法让一个角色成为两个匹配项的一部分?

https://regex101.com/r/oNfdFU/1

【问题讨论】:

  • 正则表达式的实现差异很大;你在哪里使用它(什么编程语言、库或工具)?
  • 我用过C# & .NET,它给了我和regex101一样的结果
  • 请注意,您可以简单地匹配10+,然后将每个结果字符串附加到'1',假设您知道该字符串具有有效的形式(该字符串以一个开始和结束,并且有一个或每对之间有多个零)。
  • @CarySwoveland 问题中没有任何内容定义输入的“有效形式”。据我们所知,他们可能正在一个 100MB 的文本文件中搜索此模式。

标签: c# regex


【解决方案1】:

这是在 C# 中执行此操作的一种方法。我们可以在正则表达式模式10+(?=1) 上找到所有匹配项。这使用模式末尾的前瞻来断言尾随 1,但请注意尾随 1 实际上并没有在每次匹配中消耗。它在下一场比赛开始时被消耗。然后,要构建实际的输出匹配,我们需要在每个匹配的末尾附加一个1

string input = "1010010001";
Regex regex = new Regex(@"10+(?=1)");
MatchCollection matches = regex.Matches(input);
foreach(Match match in matches)
{
    Console.WriteLine("Found a match: {0}1", match.Value);
}

打印出来:

Found a match: 101
Found a match: 1001
Found a match: 10001

【讨论】:

  • 考虑到您还没有确认字符串具有所需的形式(即匹配^(?:10+)+1$),我不明白您为什么需要前瞻。 10+还不够吗?
  • @CarySwoveland 前瞻证明 每个匹配项 具有所需的形式。如果您只匹配10+ 并附加一个 1,您将在“10201”或“10099”或实际上只是“10”之类的字符串中发明不存在的匹配项。问题中没有任何限制整个字符串的内容,只有一个示例输入。
  • @IMSoP,您假设字符串可能是'a01010b0110010c',在这种情况下'101'1001(但不是'11')将被匹配。鉴于OP的示例,您对“所需形式”的假设是否比我的更合理?无论如何,我的观点是,如果已知字符串与 ^(?:10+)+1$ 匹配,则不需要前瞻。
  • @CarySwoveland 我认为在不询问 OP 的情况下假设一种或另一种方式是不安全的,但更通用的解决方案无论如何都适用于这两种情况,并且可能对其他读者有用的网站。仅给定一个示例输入,我们可以对输出进行硬编码,但这并不能真正教给任何人任何东西,除了如何编写更好的问题。
【解决方案2】:

您可以使用捕获前瞻来捕获重叠的匹配组。

在这种情况下:

(?=(10+1))
^ ^      ^     look ahead
    ^  ^       fixed '1' The second can overlap (the first never will on LH)
     ^         '0' one or more times also can overlap
    ^   ^      capture what is seen in the look ahead   

Demo

前瞻是向前看,一步捕获。然后它会增加一个字符并再次尝试——因此每只左手在字符串中移动1

相同的正则表达式适用于 C#

Demo

或者,在 C# 中:

string input = "1010010001";
Regex regex = new Regex(@"(?=(10+1))");
MatchCollection matches = regex.Matches(input);
foreach(Match match in matches)
    {
        Console.WriteLine("Found a match: {0}", match.Groups[1]);
    }

打印:

Found a match: 101
Found a match: 1001
Found a match: 10001

顺便说一句:.NET 允许可变宽度的lookBEHINDS,所以你也可以这样做:

(?<=(10+1))

但这对于 .NET 来说是相当独特的。 PCRE 和大多数其他正则表达式风格需要固定长度的字符串来进行查找...

Demo

【讨论】:

  • 好的,但是 OP 似乎使用的是 .NET,而不是 Perl。
  • 相同的正则表达式适用于 C# Demo
  • 很遗憾这个问题被标记为重复,因为我认为你的解释比以前发布的更清楚。
猜你喜欢
  • 2019-06-14
  • 1970-01-01
  • 2020-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-01
相关资源
最近更新 更多