c# - 为什么正则表达式模式与文本不匹配?
问题描述
我有一个正则表达式模式,我想将它与我的 cron 表达式匹配:
string pattern = @"(((([0-9]|[0-5][0-9])(-([0-9]|[0-5][0-9]))?,)*([0-9]|[0-5][0-9])(-([0-9]|[0-5][0-9]))?)|(([\\*]|[0-9]|[0-5][0-9])/([0-9]|[0-5][0-9]))|([\\?])|([\\*]))[\\s](((([0-9]|[0-5][0-9])(-([0-9]|[0-5][0-9]))?,)*([0-9]|[0-5][0-9])(-([0-9]|[0-5][0-9]))?)|(([\\*]|[0-9]|[0-5][0-9])/([0-9]|[0-5][0-9]))|([\\?])|([\\*]))[\\s](((([0-9]|[0-1][0-9]|[2][0-3])(-([0-9]|[0-1][0-9]|[2][0-3]))?,)*([0-9]|[0-1][0-9]|[2][0-3])(-([0-9]|[0-1][0-9]|[2][0-3]))?)|(([\\*]|[0-9]|[0-1][0-9]|[2][0-3])/([0-9]|[0-1][0-9]|[2][0-3]))|([\\?])|([\\*]))[\\s](((([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(-([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1]))?,)*([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(-([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1]))?(C)?)|(([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])/([1-9]|[0][1-9]|[1-2][0-9]|[3][0-1])(C)?)|(L(-[0-9])?)|(L(-[1-2][0-9])?)|(L(-[3][0-1])?)|(LW)|([1-9]W)|([1-3][0-9]W)|([\\?])|([\\*]))[\\s](((([1-9]|0[1-9]|1[0-2])(-([1-9]|0[1-9]|1[0-2]))?,)*([1-9]|0[1-9]|1[0-2])(-([1-9]|0[1-9]|1[0-2]))?)|(([1-9]|0[1-9]|1[0-2])/([1-9]|0[1-9]|1[0-2]))|(((JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(-(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?,)*(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(-(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?)|((JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)/(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))|([\\?])|([\\*]))[\\s]((([1-7](-([1-7]))?,)*([1-7])(-([1-7]))?)|([1-7]/([1-7]))|(((MON|TUE|WED|THU|FRI|SAT|SUN)(-(MON|TUE|WED|THU|FRI|SAT|SUN))?,)*(MON|TUE|WED|THU|FRI|SAT|SUN)(-(MON|TUE|WED|THU|FRI|SAT|SUN))?(C)?)|((MON|TUE|WED|THU|FRI|SAT|SUN)/(MON|TUE|WED|THU|FRI|SAT|SUN)(C)?)|(([1-7]|(MON|TUE|WED|THU|FRI|SAT|SUN))?(L|LW)?)|(([1-7]|MON|TUE|WED|THU|FRI|SAT|SUN)#([1-7])?)|([\\?])|([\\*]))([\\s]?(([\\*])?|(19[7-9][0-9])|(20[0-9][0-9]))?| (((19[7-9][0-9])|(20[0-9][0-9]))/((19[7-9][0-9])|(20[0-9][0-9])))?| ((((19[7-9][0-9])|(20[0-9][0-9]))(-((19[7-9][0-9])|(20[0-9][0-9])))?,)*((19[7-9][0-9])|(20[0-9][0-9]))(-((19[7-9][0-9])|(20[0-9][0-9])))?)?)";
string text = "0 0 0 ? APR,MAY * 2020,2021,2022"
Match match = Regex.Match(text, pattern);
//the match output is: "0 0 0 ? APR,MAY *";
多年来我不知道为什么。
编辑:对不起,上一篇文章中的 javascript 标签现在我想解释为什么我这样做。它是 .net 项目中的 ac#,我想在前端检查这个,所以我很周到,这就是我放置 javascript 标签的原因。抱歉,这可能很糟糕。
关于主题:我有一个 cron 表达式,如在“字符串文本”变量中看到的上部。我想检查给定的 cron 表达式是否有效。我们可以认为 cron 表达式有 7 个字段
"Second Minute Hour DayOfMount Month DayOfWeek Year" 所有字段之间都有一个空格。字符串模式涵盖除年份以外的所有字段。
解决方案
该表达式是为 POSIX 正则表达式引擎编写/生成的。POSIX 引擎尝试匹配最长的子匹配。
C# 是一种 .NET 语言,并使用基于 PCRE 的引擎。它试图匹配最左边的子匹配。
例如,[0-9]|[0-5][0-9]
POSIX 引擎中的模式将尝试匹配“59”而不是“5”。PCRE 引擎尝试匹配最左边的,所以它只会尝试[0-9]
替代方案,并在成功时停止。
在您的模式中,对于基于 PCRE 的引擎,备选方案的顺序不是最佳的,有时甚至是错误的。这是一个重写的模式:
( #1
(
([0-5][0-9]|[0-9])
(-([0-5][0-9]|[0-9]))?
,
)*
([0-5][0-9]|[0-9])
(-([0-5][0-9]|[0-9]))?
| ([*]|[0-5][0-9]|[0-9])
\/
([0-5][0-9]|[0-9])
| [?]
| [*]
)
[\s]
( #2
(
([0-5][0-9]|[0-9])
(-([0-5][0-9]|[0-9]))?
,
)*
([0-5][0-9]|[0-9])
(-([0-5][0-9]|[0-9]))?
| ([*]|[0-5][0-9]|[0-9])
\/
([0-5][0-9]|[0-9])
| [?]
| [*]
)
[\s]
( #3
(
([0-1][0-9]|[2][0-3]|[0-9])
(-([0-1][0-9]|[2][0-3]|[0-9]))?
,
)*
([0-1][0-9]|[2][0-3]|[0-9])
(-([0-1][0-9]|[2][0-3]|[0-9]))?
| ([*]|[0-1][0-9]|[2][0-3]|[0-9])
\/
([0-1][0-9]|[2][0-3]|[0-9])
| [?]
| [*]
)
[\s]
( #4
(
([0][1-9]|[1-2][0-9]|[3][0-1]|[1-9])
(-([0][1-9]|[1-2][0-9]|[3][0-1]|[1-9]))?
,
)*
([0][1-9]|[1-2][0-9]|[3][0-1]|[1-9])
(-([0][1-9]|[1-2][0-9]|[3][0-1]|[1-9]))?
C?
| ([0][1-9]|[1-2][0-9]|[3][0-1]|[1-9])
\/
([0][1-9]|[1-2][0-9]|[3][0-1]|[1-9])
C?
| LW
| L(-([1-2][0-9]|[3][0-1]|[0-9]))?
| [1-3][0-9]W
| [1-9]W
| [?]
| [*]
)
[\s]
( #5
(
(0[1-9]|1[0-2]|[1-9])
(-(0[1-9]|1[0-2]|[1-9]))?
,
)*
(0[1-9]|1[0-2]|[1-9])
(-(0[1-9]|1[0-2]|[1-9]))?
| (0[1-9]|1[0-2]|[1-9])
\/
(0[1-9]|1[0-2]|[1-9])
| (
(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)
(-(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?
,
)*
(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)
(-(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?
| (JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)
\/
(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)
| [?]
| [*]
)
[\s]
( #6
(
[1-7]
(-[1-7])?
,
)*
[1-7]
(-[1-7])?
| [1-7]\/[1-7]
| (
(MON|TUE|WED|THU|FRI|SAT|SUN)
(-(MON|TUE|WED|THU|FRI|SAT|SUN))?
,
)*
(MON|TUE|WED|THU|FRI|SAT|SUN)
(-(MON|TUE|WED|THU|FRI|SAT|SUN))?
C?
| (MON|TUE|WED|THU|FRI|SAT|SUN)
\/
(MON|TUE|WED|THU|FRI|SAT|SUN)
C?
| ([1-7]|MON|TUE|WED|THU|FRI|SAT|SUN)
[#]
[1-7]
| ([1-7]|MON|TUE|WED|THU|FRI|SAT|SUN)
(LW|L)?
| [?]
| [*]
)
( #7
[\s]
(
(19[7-9][0-9]|20[0-9][0-9])
(-(19[7-9][0-9]|20[0-9][0-9]))?
,
)*
(19[7-9][0-9]|20[0-9][0-9])
(-(19[7-9][0-9]|20[0-9][0-9]))?
| [\s]
(19[7-9][0-9]|20[0-9][0-9])
\/
(19[7-9][0-9]|20[0-9][0-9])
| [\s]
[*]
)?
或者压缩成一个字符串:
var pattern = @"((([0-5][0-9]|[0-9])(-([0-5][0-9]|[0-9]))?,)*([0-5][0-9]|[0-9])(-([0-5][0-9]|[0-9]))?|([*]|[0-5][0-9]|[0-9])\/([0-5][0-9]|[0-9])|[?]|[*])[\s]((([0-5][0-9]|[0-9])(-([0-5][0-9]|[0-9]))?,)*([0-5][0-9]|[0-9])(-([0-5][0-9]|[0-9]))?|([*]|[0-5][0-9]|[0-9])\/([0-5][0-9]|[0-9])|[?]|[*])[\s]((([0-1][0-9]|[2][0-3]|[0-9])(-([0-1][0-9]|[2][0-3]|[0-9]))?,)*([0-1][0-9]|[2][0-3]|[0-9])(-([0-1][0-9]|[2][0-3]|[0-9]))?|([*]|[0-1][0-9]|[2][0-3]|[0-9])\/([0-1][0-9]|[2][0-3]|[0-9])|[?]|[*])[\s]((([0][1-9]|[1-2][0-9]|[3][0-1]|[1-9])(-([0][1-9]|[1-2][0-9]|[3][0-1]|[1-9]))?,)*([0][1-9]|[1-2][0-9]|[3][0-1]|[1-9])(-([0][1-9]|[1-2][0-9]|[3][0-1]|[1-9]))?C?|([0][1-9]|[1-2][0-9]|[3][0-1]|[1-9])\/([0][1-9]|[1-2][0-9]|[3][0-1]|[1-9])C?|LW|L(-([1-2][0-9]|[3][0-1]|[0-9]))?|[1-3][0-9]W|[1-9]W|[?]|[*])[\s](((0[1-9]|1[0-2]|[1-9])(-(0[1-9]|1[0-2]|[1-9]))?,)*(0[1-9]|1[0-2]|[1-9])(-(0[1-9]|1[0-2]|[1-9]))?|(0[1-9]|1[0-2]|[1-9])\/(0[1-9]|1[0-2]|[1-9])|((JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(-(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?,)*(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)(-(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC))?|(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)\/(JAN|FEB|MAR|APR|MAY|JUN|JUL|AUG|SEP|OCT|NOV|DEC)|[?]|[*])[\s](([1-7](-[1-7])?,)*[1-7](-[1-7])?|[1-7]\/[1-7]|((MON|TUE|WED|THU|FRI|SAT|SUN)(-(MON|TUE|WED|THU|FRI|SAT|SUN))?,)*(MON|TUE|WED|THU|FRI|SAT|SUN)(-(MON|TUE|WED|THU|FRI|SAT|SUN))?C?|(MON|TUE|WED|THU|FRI|SAT|SUN)\/(MON|TUE|WED|THU|FRI|SAT|SUN)C?|([1-7]|MON|TUE|WED|THU|FRI|SAT|SUN)[#][1-7]|([1-7]|MON|TUE|WED|THU|FRI|SAT|SUN)(LW|L)?|[?]|[*])([\s]((19[7-9][0-9]|20[0-9][0-9])(-(19[7-9][0-9]|20[0-9][0-9]))?,)*(19[7-9][0-9]|20[0-9][0-9])(-(19[7-9][0-9]|20[0-9][0-9]))?|[\s](19[7-9][0-9]|20[0-9][0-9])\/(19[7-9][0-9]|20[0-9][0-9])|[\s][*])?";
您可能还想在模式^
的开头和$
结尾添加。这确保在匹配的 CRON 表达式之前或之后没有额外的字符。
var pattern = @"^((([0-5] ... [\s][*])?$";
推荐阅读
- python - 尝试使用带有浏览文件的 Tkinter 单击按钮发送多封电子邮件,该文件包含 python tkinter 中的电子邮件信息
- azure - 在 Azure 上托管的 Web 应用上使用 Google 登录获取个人资料信息?
- c# - 如何将 docx 二进制数据保存到 web api C# 中的文件
- go - 如何端到端/集成测试使用反向代理管理子域的 Go 应用程序?
- amazon-web-services - 将日志数据从 ec2 日志发送到 eventbridge
- java - Spring Boot 中 WebClient 中的 POST 请求并作为 JSONObject 接收响应
- wordpress - Wordpress 为用户创建收藏夹列表
- youtube-data-api - 配额视图:每日查询数图表不显示任何数据
- c++ - 如果 std::vector::clear() 不是静态的,如何在没有实例的情况下调用它?
- javascript - 'length' 和 '__proto__' 是由 'getter' 和 'setter' 组成的吗?