【问题标题】:C# / Regex Pattern works in online testing, but not at runtimeC#/Regex 模式适用于在线测试,但不适用于运行时
【发布时间】:2019-03-30 17:36:18
【问题描述】:

使用以下 RegEx 模式:

(?<comment>(^#{2} [^\r\n]+[\s]+)*)(?:^\[(?:(?<hive>HK(?:LM|[DP]D|C[CUR]|U(SERS|SER|SR|S)))[:])?(?<name>[a-z0-9$][a-z0-9-_]{2,63})\])(?<items>[\S\s]*?)(?=\n{2,})

解析以下文本:

[HKLM:Connection]
   AuthKey = 0x8a79b42z67fct29b42e07b3fd78nc540
   Url = https://dev.somewebsite.com
   ApiPath = /api/

[HKLM:Settings]
   AutoMinimizeConsole = no
   StyleFile = Default
   PhoneNbrs = [+]?[01]{0,3}[-. ]?[(]?[0-9][0-9][0-9][)]?[-. ]?[0-9][0-9][0-9][-. ]?[0-9][0-9][0-9][0-9]
   PostalCodes = [ABCEGHJKLMNPRSTVXYabceghjklmnprstvxy][0-9][ABCEGHJKLMNPRSTVWXYZabceghjklmnprstvwxyz][\s.-]?[0-9][ABCEGHJKLMNPRSTVWXYZabceghjklmnprstvwxyz][0-9]

[HKLM:Font-Mapping]
   MonoSpaced = Courier New
   User1 = Software Tester 7
   User2 = Repetition Scrolling
   User3 = basis333

[HKLM:UserInterface]

[HKCU:UserInterface]

[HKCU:Credentials]
   Username =
   Password? =

当输入在线正则表达式测试时,结果如预期一样,但在代码中,找不到匹配项。 此处使用的“数据”变量在此段之前使用上面提供的文本填充:

public const string GROUP_PATTERN = @"(?<comment>(^#{2} [^\r\n]+[\s]+)*)(?:^\[(?:(?<hive>HK(?:LM|[DP]D|C[CUR]|U(SERS|SER|SR|S)))[:])?(?<name>[a-z0-9$][a-z0-9-_]{2,63})\])(?<items>[\S\s]*?)(?=\n{2,})";
Regex groupParser = new Regex(GROUP_PATTERN, RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase | RegexOptions.Multiline);
MatchCollection matches = groupParser.Matches(data);
foreach (Match m in matches)
    this.Add(IniGroupItem.Parse(m.Value));

在 ForEach 开始时,匹配项为零(应该是六个!)..

由于该模式在测试站点上有效,但在 c# 中完全无效,我不知道如何找出编译器遇到的问题。有什么见解/建议吗?

【问题讨论】:

  • 您的文件似乎有 CRLF 结尾,请尝试将 (?=\n{2,}) 替换为 (?=(?:\r\n){2,})
  • doh! -- 好吧,我把 "(?=\n{2,})" 替换为 "(?=[\r\n]{3,})" ,它按预期工作!如果您将其发布为答案,我会给您功劳! :)

标签: c# regex


【解决方案1】:

大多数在线正则表达式测试器中的行尾仅是 LF。如果您在 RegexStorm .NET 正则表达式测试器上测试了您的 .NET 正则表达式,您会更快地发现问题,因为它的行结尾是 CRLF。

所以,问题在于(?=\n{2,}),因为它需要换行符重复 2 次或更多次。由于实际数据中有两个或多个\r\n 序列,您需要用(?=(?:\r\n){2,}) 替换该模式部分。

如果你说(?=[\r\n]{3,}) 适合你,这意味着你想匹配一个位置,后跟 3 个或更多 LF 或 CR 字符。

在混合情况下,如果您想匹配一个后跟 2 个或更多 CLF 或 LF 换行符序列的位置,您可以使用(?=(?&gt;\r\n?|\n){2,})

【讨论】:

  • 正如我之前提到的,我选择了 (?=[\r\n]{3,}) ,它不关心序列或要求两个字符都存在。有没有理由说这种方法不如你的方法?
  • @BrettLeuszler 这完全取决于您的要求。如果要匹配后跟 3 个或更多 LF 或 CR 字符的位置,请使用 (?=[\r\n]{3,})。如果你想匹配一个后跟 2 个或更多换行序列的地方,(?=(?&gt;\r\n?|\n){2,}) 更精确
  • 我对使用 "\r\n" 作为严格文字的担忧是,我遇到过传入文本的顺序(令人讨厌!)颠倒(LFCR 而不是 CRLF)的情况。从那以后,我更喜欢“[\r\n]{2}”而不是严格的文字“\r\n”,所以这就是我反射性地回到那个模式的原因。
  • 另外,还有(哈哈)——我主要使用regex101.com 进行正则表达式测试,主要是因为它提供了大量的诊断信息,可以真正深入到模式的语法中,而且很容易它提供的可访问帮助。不过,显然,在解析源文本时,它显然存在您在 CRLF 与 LF 中识别出的问题,因此最好有另一个资源来检查!
猜你喜欢
  • 1970-01-01
  • 2013-10-01
  • 1970-01-01
  • 2022-11-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-05-01
相关资源
最近更新 更多