0

我在 PHP 中有一个正则表达式来匹配一些这样的文本:

第 24 次会议 - 敏捷的棕狐 [2012 年 1 月 10 日至 2012 年 9 月 26 日]

我想出的模式如下所示:

$pattern = "/(([0-9]{1,2})(st|nd|rd|th)\sMeeting\s-\s)?(.*)(\[([0-9]{1,2}\s(January|February|March|April|May|June|July|August|September|November|December)\s[0-9]{4})\sto\s([0-9]{1,2}\s(January|February|March|April|May|June|July|August|September|November|December)\s[0-9]{4})\])$/"

这似乎工作正常。

但是,我希望最后的日期部分是可选的。但是,当我添加 ? 在日期分组之后, preg_match 不再提取字符串中的日期。我怀疑 .* 正在接管,但我似乎无法理解

4

3 回答 3

1
(.*) --> (.*?)

在此处阅读有关惰性量词的更多信息:

http://www.regular-expressions.info/repeat.html

于 2013-01-06T20:10:00.127 回答
0

正如您所推测的那样,.*(贪婪的量词)消耗了太多信息。这可以通过使其变得懒惰或用其他东西替换它来解决,例如[^[]*. 但是,用后一个建议替换它将不允许[在字符串中使用任何文字。

除了解决此问题之外,您还应该做的是学习对不需要保存的部分使用非捕获组。这将加快您的正则表达式并节省一些内存。

这是我对您的问题的解决方案。变化不大,但我相信你能发现差异。

/(([0-9]{1,2})(st|nd|rd|th)\sMeeting\s-\s)?(.*)(\[([0-9]{1,2}\s(January|February|March|April|May|June|July|August|September|November|December)\s[0-9]{4})\sto\s([0-9]{1,2}\s(January|February|March|April|May|June|July|August|September|November|December)\s[0-9]{4})\])?$/

您可以在此处查看演示和正则表达式说明:http ://regex101.com/r/vZ1nH6

该网站使用 PHP,因此可以准确解决您的问题。如果您有兴趣了解更多信息,我建议您在 www.regular-expressions.info 上阅读正则表达式,并在http://www.regex101.com/quiz/上查看测验

于 2013-01-06T20:10:26.097 回答
0

这个小改动就可以了(粗体)

/(([0-9]{1,2})(st|nd|rd|th)\sMeeting\s-\s)? (.*?) (\[([0-9]{1,2}\s(January|February|March|April|May|June|July|August|September|November|December)\s[0-9]{4})\sto\s([0-9]{1,2}\s(January|February|March|April|May|June|July|August|September|November|December)\s[0-9]{4})\]|$)$/

首先,自由文本表达式由 a 扩展?以使其不贪婪(参见其他帖子)

than|$被附加到日期部分以告诉它恰好是日期或字符串的结尾。

这是你的总正则表达式

/(([0-9]{1,2})(st|nd|rd|th)\sMeeting\s-\s)?(.*?)(\[([0-9]{1,2}\s(January|February|March|April|May|June|July|August|September|November|December)\s[0-9]{4})\sto\s([0-9]{1,2}\s(January|February|March|April|May|June|July|August|September|November|December)\s[0-9]{4})\]|$)$/

于 2013-01-06T20:24:29.757 回答