7

我有一个在http://gskinner.com/RegExr/上测试过的正则表达式,它有效,但是当我在我的 C# 应用程序中使用它时它失败了。

我的正则表达式:(?<!\d)\d{6}\K\d+(?=\d{4}(?!\d)) 文本:4000751111115425 结果:111111

我的正则表达式有什么问题?

4

2 回答 2

6

您遇到的这个问题是 .NET 正则表达式不支持\K“丢弃迄今为止匹配的内容”。

我相信您的正则表达式翻译为“匹配任何超过十\d位数字的字符串,尽可能多的数字,并丢弃前 6 位和后 4 位”。

我相信 .NET 兼容的正则表达式

(?<=\d{6})\d+(?=\d{4})

达到同样的目的。请注意,no-more- \ds 的负前瞻/后视是不必要的,因为它\d+是贪婪的 - 引擎已经尝试匹配尽可能多的数字。

于 2017-11-21T07:54:34.490 回答
-1

一般来说,\K操作符(从匹配内存缓冲区中丢弃所有匹配的文本)可以用两种技术模拟:

例如,

  • PCRE a+b+c+=\K\d+演示)= .NET(?<=a+b+c+=)\d+a+b+c+=(\d+)(并获取第 1 组值)
  • PCRE ^[^][]+\K.*( demo ) = .NET (?<=^[^][]+)(?:\[.*)?$( demo ) 或 (这里更好) ^[^][]+(.*)( demo )。

第二个示例的问题在于,它[^][]+可以匹配相同的文本.*(这些模式重叠),并且由于两个模式之间没有明确的界限,因此仅使用后视实际上并不能正常工作,需要额外的技巧才能使其工作。

捕获组方法在这里是普遍的,应该适用于所有情况。

由于\K使正则表达式引擎“忘记”到目前为止消耗的匹配部分,因此这里最好的方法是使用捕获组来获取您需要在左侧上下文之后获取的匹配部分:

using System;
using System.Text.RegularExpressions;

public class Test
{
    public static void Main()
    {
        var text = "Text  4000751111115425";
        var result = Regex.Match(text, @"(?<!\d)\d{6}(\d+)(?=\d{4}(?!\d))")?.Groups[1].Value;
        Console.WriteLine($"Result: '{result}'");
    }
}

请参阅在线 C# 演示正则表达式演示(请参阅选项卡以获取正确的结果表)。详情

  • (?<!\d)- 左侧数字边界
  • \d{6}- 六位数
  • (\d+)-捕获组 1:一位或多位数字
  • (?=\d{4}(?!\d))- 与紧随其后的四个数字而不是紧随另一个数字的位置相匹配的正向前瞻。
于 2022-02-16T22:38:28.367 回答