正则表达式后视问题

时间:2013-11-24 18:55:01

标签: php python regex lookbehind

我试图编写一个正则表达式来从历史文件中提取文本块,我保留在我正在构建的项目中。目前我计划在我的文本编辑器(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\.]+$ 

我一直在四处寻找,到目前为止看起来这种外观格式是正确的。我似乎无法弄清楚我错过了什么。有什么想法吗?

2 个答案:

答案 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.]+$

Online demo

备注:

  • (?m):是内联regex modifier
  • 您不需要在字符类中转义点.[.]将匹配点而不是任何字符
  • 您可以为空白字符添加一些量词:\s*\s+
  • \w+也会匹配下划线_,因此要排除它,您可以使用[^\W_]+
  • 正则表达式 非常棒

答案 1 :(得分:1)

PHP和Python都不允许任意长度的后视。因此,只要你有一个像+这样的量词,就会停止工作。

所以你的第一次尝试是唯一可行的。