正则表达式抓住额外的角色

时间:2012-08-05 01:27:37

标签: php regex

我正在使用PHP preg_replace以及以下正则表达式:

/(?<=#EXTINF:([0-9])+,).+?(?=#EXT)/gsm

对以下字符串进行操作:

#EXTM3U
#EXT-X-TARGETDURATION:10
#EXTINF:10,
Grab_this_string
#EXTINF:5,
Grab_this_string_too
#EXT-X-ENDLIST

取代:

, Grab_this_string 
Grab_this_string_too

我正在尝试匹配它而没有第一个逗号(基本上是#EXTINF:xx,和下一个#EXTINF之间的所有内容:

Grab_this_string 
Grab_this_string_too

1 个答案:

答案 0 :(得分:2)

由于您处于多线模式,因此您可以匹配在线结尾以描绘每一行。

这匹配两行并仅用第一行替换它们(有效地删除第二行)。请注意我已删除&#34; dotall&#34;模式(s)。

$regex = '/(^#EXTINF:\d+,$)(\s+)^.+$(?=\s+^#EXT)/m';

echo preg_replace($regex, '$1', $str);

输出:

#EXTM3U
#EXT-X-TARGETDURATION:10
#EXTINF:10,
#EXTINF:5,
#EXT-X-ENDLIST

更新

使用lookbehind不起作用,因为它需要可变长度匹配,这在大多数正则表达式引擎(包括PHP使用的PCRE)中都不受支持。

如果您只想捕获要删除的行而不必像上面那样使用子模式匹配替换两行,则可以使用\K转义序列来模拟不受主题影响的后备到可变长度限制。 \K重置了匹配的开始位置,因此在\K之前匹配的所有内容都不会包含在最终匹配中。 (参见last paragraph here。)

$regex = '/^#EXTINF:\d+,\s+\K^.+?(?=#EXT)/sm';

echo preg_replace($regex, '', $str);