看看 Regx 的魔力
$string = <<<CUT
#EXTM3U
#EXTINF:-1 tvg-id="" tvg-name="A&E" tvg-logo="" group-title="ENTRETENIMIENTO",A&E`http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts
http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts
#EXTINF:-1 tvg-id="" tvg-name="ABC Puerto Rico" tvg-logo="" group-title="NACIONALES",ABC Puerto Rico
http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/96.ts
CUT;
preg_match_all('/(?P<tag>#EXTINF:-1)|(?:(?P<prop_key>[-a-z]+)=\"(?P<prop_val>[^"]+)")|(?<something>,[^\r\n]+)|(?<url>http[^\s]+)/', $string, $match );
$count = count( $match[0] );
$result = [];
$index = -1;
for( $i =0; $i < $count; $i++ ){
$item = $match[0][$i];
if( !empty($match['tag'][$i])){
//is a tag increment the result index
++$index;
}elseif( !empty($match['prop_key'][$i])){
//is a prop - split item
$result[$index][$match['prop_key'][$i]] = $match['prop_val'][$i];
}elseif( !empty($match['something'][$i])){
//is a prop - split item
$result[$index]['something'] = $item;
}elseif( !empty($match['url'][$i])){
$result[$index]['url'] = $item ;
}
}
print_r( $result );
退货
array (
0 =>
array (
'tvg-name' => 'A&E',
'group-title' => 'ENTRETENIMIENTO',
'something' => ',A&E`http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts',
'url' => 'http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts',
),
1 =>
array (
'tvg-name' => 'ABC Puerto Rico',
'group-title' => 'NACIONALES',
'something' => ',ABC Puerto Rico',
'url' => 'http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/96.ts',
),
)
说真的,尽管我不知道其中一些是什么something。无论如何应该让你开始。
对于正则表达式,分解后实际上非常简单。真正的诀窍是使用preg_match_all 而不是preg_match。
这是我们的正则表达式
/(?P<tag>#EXTINF:-1)|(?:(?P<prop_key>[-a-z]+)=\"(?P<prop_val>[^"]+)")|(?<something>,[^\r\n]+)|(?<url>http[^\s]+)/
首先,我们将把它分解成更易于管理的部分。这些由管道| 分隔,用于或。每一个都可以被认为是一个单独的模式,匹配这个或下一个。现在,顺序可能很重要,因为它们将从左到右匹配,所以如果一个匹配在左边,它就会停止。所以你必须小心不要有一个可以在两个地方匹配的正则表达式(如果你不想要那个)。但是,它也可以为您所用,如下所示。这确实是我们正在处理的问题
(?P<tag>#EXTINF:-1)
(?:(?P<prop_key>[-a-z]+)=\"(?P<prop_val>[^"]+)")
(?<something>,[^\r\n]+)
(?<url>http[^\s]+)
四个正则表达式。对于所有这些(?P<name>...) 是一个命名的捕获组,它只是使它更具可读性,更容易找到位。如果您查看我用来查找匹配项的条件,例如!empty($match['tag'][$i]),我们可以使用tag 索引/键,因为有一个命名的捕获组,否则它将是1。将许多 regx 放在一起,如果您认为这实际上是嵌套的,那么 1 2 3 可能会变得混乱,因此标签等将是 $match[1][$i] 。无论如何,一旦取出,我们就有了
-
#EXTINF:-1 从字面上匹配这个字符串
-
(?:(?P<prop_key>[-a-z]+)=\"(?P<prop_val>[^"]+)") 这更复杂 (?: .. ) 是一个非捕获组,这是所以键/值在匹配数组中以相同的索引结束,但没有一起捕获,分解这是 ([-a-z]+)=\"([^"]+)\" 或匹配一个单词然后是=,然后是",而不是",以"结尾。基本上一侧捕获键,另一侧捕获不包括双引号的值
-
,[^\r\n]+ 以逗号开头,然后是回车符
- 最后一个
http[^\s]一个网址
现在请记住我说过的关于顺序很重要的内容,这个 url http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts 将匹配最后一个表达式,除了它以 ,A&Ehttp://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts` 开头,它匹配第三个,所以它永远不会到达数字 4
希望对您有所帮助,前提是您必须对 Regx 有一个基本的了解,这并不是一个完整教程的地方,您可以在几分钟内找到更好的示例,然后我可以提供。
为了完整起见,这里是preg_match_all 返回的部分内容
(
[0] => Array(
[0] => #EXTINF:-1
[1] => tvg-name="A&E"
[2] => group-title="ENTRETENIMIENTO"
[3] => ,A&E`http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts
[4] => http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/76.ts
[5] => #EXTINF:-1
[6] => tvg-name="ABC Puerto Rico"
[7] => group-title="NACIONALES"
[8] => ,ABC Puerto Rico
[9] => http://nxtv.tk:8080/live/jarenas/iDKZrC56xZ/96.ts
)
[tag] => Array(
[0] => #EXTINF:-1
[1] =>
[2] =>
[3] =>
[4] =>
[5] => #EXTINF:-1
[6] =>
[7] =>
[8] =>
[9] =>
)
[1] => Array(
[0] => #EXTINF:-1
[1] =>
[2] =>
[3] =>
[4] =>
[5] => #EXTINF:-1
[6] =>
[7] =>
[8] =>
[9] =>
)
[prop_key] => Array(
[0] =>
[1] => tvg-name
[2] => group-title
[3] =>
[4] =>
[5] =>
[6] => tvg-name
[7] => group-title
[8] =>
[9] =>
)
[2] => Array( ... duplicate of prop_key .. )
etc.
)
在上面的数组中找到item的方法是,如果你在第一次运行索引0时查看for循环,匹配的主要部分$match[0][$i]包含所有匹配,但@987654354 @array 仅包含与该 regx 匹配的项目,我们可以使用 $i 索引将它们关联起来。
if( !empty($match['tag'][$i])){
//is a tag increment the result index
++$index;
}
如果$match[tag][$i] 不为空。如果您在$i = 0 时查看$match[tag][0],您会发现它确实不是空的。在第二个循环中,$match[tag][1] 是空的,但 $match[prop_key][1] 不是,所以我们知道当 $i = 1 项目是 prop_key 匹配时。这就是它的工作原理。
-ps- 如果您能找到删除重复数字索引的方法,请与我分享...大声笑...如果我没有使用命名捕获组,这些是正常匹配,正如我所说它可能会变得混乱。