我试图编写一个正则表达式来从历史文件中提取文本块,我保留在我正在构建的项目中。目前我计划在我的文本编辑器(textmate或sublimetext 2)中手动执行此提取,但最终我将使用python或php将其构建为脚本化进程(避难所&t; t决定了)。
我的历史记录文件中的所有历史记录条目都具有以下格式:
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\.]+$
我一直在四处寻找,到目前为止看起来这种外观格式是正确的。我似乎无法弄清楚我错过了什么。有什么想法吗?
答案 0 :(得分:2)
正如Joey所述,php或python中没有任意长度的lookbehind。但PHP中有一个解决方法! \K
转义序列。
来自docs:
转义序列\ K会导致以前不匹配的任何字符 包含在最终匹配的序列中。例如,模式:
foo\Kbar
匹配“foobar”,但报告它匹配“bar”。此功能 类似于lookbehind断言(如下所述)。但是,在这种情况下,真实匹配之前的主题部分不必具有固定长度,如同后瞻性断言那样。
删除一些冗余括号[]
后,表达式看起来像
(?m)^\d{4}-\d{2}-\d{2}\s-\s\w+\s--\sVersion:\s\K[\d.]+$
备注:强>
(?m)
:是内联regex modifier .
:[.]
将匹配点而不是任何字符\s*
或\s+
\w+
也会匹配下划线_
,因此要排除它,您可以使用[^\W_]+
答案 1 :(得分:1)
PHP和Python都不允许任意长度的后视。因此,只要你有一个像+
这样的量词,就会停止工作。
所以你的第一次尝试是唯一可行的。