【问题标题】:Year not displaying correctly with regex正则表达式无法正确显示年份
【发布时间】:2015-05-12 08:57:54
【问题描述】:

使用正则表达式匹配这行文本我发现年份仍然显示为2015-01-07 而不仅仅是2015。谁能看到我的正则表达式有什么问题?

代码行:

    2015-01-07 Wed Jan 07 11:03:43.390 DD Started

我的正则表达式:

    (?<date>(?<year>(?:\d{4}|\d{2})-(?<month>\d{1,2})-(?<day>\d{1,2})))\s(?<logEntry1>.*)\s(?<logEntry2>.*)\s(?<logEntry3>.*)\s(?<time>(?<hour>\d{2}):(?<minutes>\d{2}):(?<seconds>\d{2}).(?<milli>\d{0,3}))\s(?<logEntry>.*)

为什么我不能单独列出“年份”? 我通过 regex101.com 运行它,这里是捕获组值:

    MATCH 1
    date    [0-10]  `2015-01-07`
    year    [0-10]  `2015-01-07`
    month   [5-7]   `01`
    day [8-10]  `07`
    logEntry1   [11-14] `Wed`
    logEntry2   [15-18] `Jan`
    logEntry3   [19-21] `07`
    time    [22-34] `11:03:43.390`
    hour    [22-24] `11`
    minutes [25-27] `03`
    seconds [28-30] `43`
    milli   [31-34] `390`
    logEntry    [35-45] `DD Started`

【问题讨论】:

  • 您的正则表达式期望日期为 yymmdd 而在日志中为 ddmmyy。
  • 很抱歉。我那里的代码行不正确。现在改了,但问题依旧存在。
  • 请注意,未转义的点将匹配任何字符。

标签: c# regex


【解决方案1】:

你应该把括号从)))移到(?:\d{4}|\d{2}))

(?<date>(?<year>(?:\d{4}|\d{2}))-(?<month>\d{1,2})-(?<day>\d{1,2}))\s(?<logEntry1>.*)\s(?<logEntry2>.*)\s(?<logEntry3>.*)\s(?<time>(?<hour>\d{2}):(?<minutes>\d{2}):(?<seconds>\d{2}).(?<milli>\d{0,3}))\s(?<logEntry>.*)

实际上,我宁愿将 VERBOSE 正则表达式选项与这么长的正则表达式一起使用,并使用像 # Year 这样的 cmets 来跟踪你里面的内容:

var rx = new Regex(@"(?<date>
     (?<year>
       (?:\d{4}|\d{2})
     )                  # Year
     -
     (?<month>\d{1,2})
     -
     (?<day>\d{1,2})
   )                    # Date
   \s
   (?<logEntry1>.*)
   \s
   (?<logEntry2>.*)
   \s
   (?<logEntry3>.*)
   \s
   (?<time>
     (?<hour>\d{2})
     :
     (?<minutes>\d{2})
     :
     (?<seconds>\d{2})
     .
     (?<milli>\d{0,3})
   )
   \s
   (?<logEntry>.*)", RegexOptions.IgnorePatternWhitespace);

结果:

【讨论】:

  • 做了同样的测试,发现同样的结果,这是正确的答案 OP
  • 谢谢@stribizhev。在使用 RegEx 时,我总是被一些小细节所困扰。
【解决方案2】:
(?<date>(?<year>(?:\d{4}|\d{2}))-(?<month>\d{1,2})-(?<day>\d{1,2}))\s(?<logEntry1>.*?)\s(?<logEntry2>.*?)\s(?<logEntry3>.*?)\s(?<time>(?<hour>\d{2}):(?<minutes>\d{2}):(?<seconds>\d{2}).(?<milli>\d{0,3}))\s(?<logEntry>.*)

                              ^^

试试这个。查看演示。一年后你错过了)

https://regex101.com/r/oF9hR9/16

【讨论】:

  • 我不会说错过,因为它存在于模式中。只是放错地方了。
  • 谢谢@vks。这行得通。我应该在末尾添加另一个 ')' 来结束年份部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-10-30
  • 1970-01-01
  • 1970-01-01
  • 2016-06-25
  • 1970-01-01
  • 1970-01-01
  • 2015-12-25
相关资源
最近更新 更多