【发布时间】:2013-11-24 18:55:00
【问题描述】:
我正在尝试编写一个正则表达式来从我正在构建的项目中保存的历史文件中提取文本块。目前我正计划在我的文本编辑器(textmate 或 sublimetext 2)中手动进行此提取,但最终我将使用 python 或 php(尚未决定)将其构建到脚本过程中。
我的历史文件中的所有历史条目都具有以下格式:
YYYY-MM-DD - Chris -- Version: X.X.X
====================================
- Lorem ipsum dolor sit amet, vim id libris epicuri
- Et eos veri quodsi appetere, an qui saepe malorum eloquentiam.
...
--
其中 X 是工作的版本号。
我正在尝试将所有内容从版本号拉到最后的双破折号分隔符,它表示文本块的结尾。
我首先创建了正则表达式语句来选择有效的部分标题:
(^[\d]{4}-[\d]{2}-[\d]{2}\s-\s[\w]+\s--\sVersion:\s)[\d\.]+$
但是当我尝试将括号中的模式转换为它背后的外观时失败了:
(?<=^[\d]{4}-[\d]{2}-[\d]{2}\s-\s[\w]+\s--\sVersion:\s)[\d\.]+$
我一直在环顾四周,到目前为止,这种lookbehind 格式似乎是正确的。我似乎无法弄清楚我错过了什么。有什么想法吗?
【问题讨论】:
-
Lookbehind 几乎从不这样使用。
-
知道了,我想这是极少数情况之一;)
-
我说几乎从不,因为你可以简单地捕捉你想要的东西,而不用从匹配中排除任何东西,所以你不使用它来强制执行条件。您正在使用它来排除不必要的匹配(组 0)。
-
啊,好的。根据您的第一条评论,我没有意识到这就是您的意思。我想我仍然有点模糊为什么我不想按照我概述的方式去做。如果该语句表示一个文本块的开始,那么除了版本号之外我什么都不想要,并且除了该字符串匹配之外,没有真正不同的方式来告诉特定块从哪里开始,为什么要我还想在后面的look中包含字符串?
-
这里是一个例子,不要往后看:
$string = "2013-11-25 - Chris -- Version: 2.1.7\nwhat-1\n--\n2013-11-25 - Fred -- Version: 2.1.7\nwhat-2";$count = preg_match_all('/^\d{4}-\d{2}-\d{2}\s-\s(\w+)\s--\sVersion:\s([\d\.]+)(.*?)(?:^--|(?![\S\s]))/sm',$string,$matches);for($i=0;$i<$count;$i++){ print ( "who=" . $matches[1][$i] . "\n" ); print ( "vers=" . $matches[2][$i] . "\n" ); print ( "what=" . $matches[3][$i] . "\n----------\n" );}
标签: php python regex lookbehind