在正则表达式结束时使组可选使得它永远不会匹配

时间:2013-01-06 19:40:15

标签: php regex

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

  

第24次会议 - 快速棕色狐狸[2012年1月10日至9月26日   2012]

我提出的模式看起来像这样:

$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不再拉出日期。我怀疑。*正在接管,但我似乎无法得到它

3 个答案:

答案 0 :(得分:1)

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

在这里阅读更多关于懒惰量词的信息:

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

答案 1 :(得分:0)

正如您所假设的那样,.*(贪婪的量词)会消耗太多信息。这可以通过使其 lazy 或用其他内容替换它来解决,例如[^[]*。但是,用后一个建议替换它将禁止在字符串中使用文字[

除了解决此问题之外,您还应该学习如何将非捕获组用于不需要保存的部分。这将加速你的正则表达并节省一些内存。

这是我解决您问题的方法。没有太大的改变,但我相信你可以发现差异。

/(([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/上的测验

答案 2 :(得分: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})\] |$ )$/

首先将自由文本表达式扩展为?以使其不合适(参见其他帖子)

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

这是你的正则表达式

/(([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})\]|$)$/