4

我正在使用preg_replace带有以下正则表达式的 PHP:

/(?<=#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
4

1 回答 1

2

Since you're in multiline mode, you could match on line endings to delineate each line.

This matches two lines and replaces them with the first line only (effectively removing the second line). Notice I've removed "dotall" mode (s).

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

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

Output:

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

Update:

Using a lookbehind will not work, as it requires variable-length matching, which is unsupported in most regex engines (including PCRE, which PHP uses).

If you want to capture only the line you want to remove and not have to replace two lines with a subpattern match like I did above, you can use the \K escape sequence to simulate a lookbehind that is not subject to variable-length restrictions. \K resets the match's start position, so anything that was matched before the \K will not be included in the final match. (See the last paragraph here.)

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

echo preg_replace($regex, '', $str);
于 2012-08-05T01:55:18.933 回答