本帖最后由 silverchs 于 2019-5-29 21:30 编辑
发帖的起因:
无意中在论坛里看到了这个求助帖:https://www.right.com.cn/forum/thread-528915-1-3.html
发现这位“@孤独的飞”朋友从网上照抄\+?ChannelName=\"(.+?)\",ChannelURL=\".+?://(.+?)\".\+?这个表达式,不会变通,提取出来的格式乱七八糟,简直惨不忍睹啊!
虽然我对正则表达式也不是很了解,但是我研究了一下,还是能写出正确的提取表达式,可能我写的表达式还不够精简,但是能达到目的就好了,我的要求也不是很高
还是以孤独的飞帖子中给出的源为例子:jsSetConfig('Channel','ChannelID="ch09093013432729643599",ChannelName="CCTV1HD",UserChannelID="1",ChannelURL="igmp://239.254.104.96:8550",TimeShift="1",ChannelSDP="",TimeShiftURL="rtsp://27.31.203.146:554/live/ch09093013432729643599.sdp?playtype=1&boid=001&backupagent=121.60.255.132:1556&clienttype=1&time=20190402135617+08&life=172800&ifpricereqsnd=1&vcdnid=vcdn001&userid=sy1812345&mediaid=ch09093013432729643599&ctype=5&TSTVTimeLife=3600&contname=&authid=0&UserLiveType=1&stbid=0010049900608930182700000&nodelevel=3&terminalflag=1&bitrate=2000",ChannelLogURL="",PositionX="20",PositionY="20",BeginTime="0",Interval="1",Lasting="1",ChannelType="2",ChannelPurchased="",LocalTimeShift="0",UserTeamChannelID="1",FCCFunction="1",ChannelFCCIP="121.60.213.228",ChannelFCCPort="15970"');
下面就是我按照\+?ChannelName=\"(.+?)\",ChannelURL=\".+?://(.+?)\".\+?这个表达式的思路写出的有效表达式。
提取组播rtp直播源的正则表达式
查找目标:- ^.*ChannelNa\+?me="(.+?)"\,UserChannelID="(.+?)"\,ChannelURL="(.+?)://(.+?)",Time.*$
复制代码
替换为:- #EXTINF:-1,\1\nrtp://\4\n
复制代码
替换后的格式:
#EXTINF:-1,CCTV1HD
rtp://239.254.104.96:8550
提取单播rtsp直播源的正则表达式
查找目标:- ^.*ChannelNa\+?me="(.+?)"\,(?=UserChannelID)(.+?)(?=,TimeShiftURL=)\,TimeShiftURL="(.+?)://(.+?)"\,ChannelLog.*$
复制代码
替换为:
替换后的格式:
#EXTINF:-1,CCTV1HD
rtsp://27.31.203.146:554/live/ch ... flag=1&bitrate=2000
简单解释一下:
1.组播表达式
^.*ChannelNa的目的是筛选出从句首到ChannelName之间的内容:jsSetConfig('Channel','ChannelID="ch09093013432729643599",
+?me=\"(.+?)"的目的就是匹配频道名称,这里的(.+?)就是组播替换表达式里的\1了
,UserChannelID="(.+?)"的目的是把,UserChannelID="1"这段无用的信息筛选出来,这里的(.+?)就是\2了
,ChannelURL="(.+?)://(.+?)"的目的是把组播源筛选出来,这里的(.+?)就是\3和组播替换表达式里的\4了
,Time.*$的目的是把组播源后面的无用信息筛选出来
2.单播表达式
这里^.*ChannelNa和+?me=\"(.+?)"和组播表达式的目的是一样的
,(?=UserChannelID)(.+?)(?=,TimeShiftURL=)的目的是把频道名称和单播rtsp地址之间的无用信息筛选出来
,TimeShiftURL="(.+?)://(.+?)"的目的是筛选单播rtsp地址,这里的(.+?)就是单播替换表达式里的\3和\4了
,ChannelLog.*$的目的是把单播源后面的无用信息筛选出来
########################################################################################
#25楼的朋友又提出了另一种源的格式:
下面如何处理
code: "02000001000000050000000000000003",
title: "广东体育",
subTitle: "广东体育",
channelnum: "005",
icon: "http://183.235.16.92:8081/pics/category/201610/08/2016100817384080885805.png",
timeshiftAvailable: "true",
lookbackAvailable: "true",
params: {
zteurl: "rtp://239.20.0.114:2026",
hwmediaid: "10000100000000060000000000128485",
hwcode: "10000100000000050000000000088754",
hwurl: "rtp://239.10.0.124:1025",
ztecode: "ch000000000000114"
我也顺便把处理过程简单说明一下,让大家认识更多类型的源处理的方法:这种情况最大的问题是频道的信息不在同一行,信息比较分散,首先要做的就是把频道的有效信息提取到同一行里,才能用正则表达式批量处理。
1.提取有效信息:可以通过Notepad++的标记功能就可以了,分别把sub、zteurl和hwurl所在的行标记出来,然后通过标签功能把未标记的行都删掉,就能把下面的有效信息保留下来了。
subTitle: "广东体育",
zteurl: "rtp://239.20.0.114:2026",
hwurl: "rtp://239.10.0.124:1025",
再查找正则表达式^\s替换掉,就可以把前面的空格符都删除了,得到了下面的内容
subTitle: "广东体育",
zteurl: "rtp://239.20.0.114:2026",
hwurl: "rtp://239.10.0.124:1025",
2.通过替换\r\n把三行内容连接成一行,用\r\nzteurl替换zteurl,用\r\nhwurl替换hwurl,就能得到下面的内容
subTitle: "广东体育",zteurl: "rtp://239.20.0.114:2026",hwurl: "rtp://239.10.0.124:1025",
3.这时就可以通过写正则表达式提取内容了
查找目标:- subTitle: "(.+?)",zteurl: "(.+?)",hwurl: "(.+?)",
复制代码
替换为:- #EXTINF:-1,\1\n\2\n#EXTINF:-1,\1\n\3\
复制代码
替换后得到了下面的内容:
#EXTINF:-1,广东体育
rtp://239.20.0.114:2026
#EXTINF:-1,广东体育
rtp://239.10.0.124:1025
或者替换为:
替换后得到了下面的内容:
#EXTINF:-1,广东体育
rtp://239.20.0.114:2026#rtp://239.10.0.124:1025
########################################################################
继续更新
发现此贴:https://www.right.com.cn/forum/thread-601053-1-1.html
针对此帖子给出的抓包源格式,我给出了下面的回复,大家可以作为例子参考
抱歉现在才看到你的帖子,可能有点迟了,但是还是把我的处理方法写出来吧,给你作为参考,希望你能对正则表达式有更深的了解。
1.你分享的格式全部频道内容全都在一行里面,要分行才能更好的处理:
找出各个频道的共同开始头,就是{ "code":"了,然后通过查找目标:{ "code":"替换为:\r\n{ "code":",这样就可以快速把不同频道分行了。
2.以广东珠江频道为例,根据分行后的格式写出替换正则表达式:- .*subTitle":"(.*?)",.*zteurl":"(.*?)".*hwurl":"(.*?)".*
复制代码
按照你的格式要求,替换为:
,这样就可以达到你的提取格式要求了。
3.按照上面的正则替换本以为可以一步到位,但是替换后发现只有部分频道处理成功,还有一些频道原封未动。
按理来说,服务器下发的频道信息格式应该都是是统一的,但是我通过对比发现,居然有两种不同的信息格式,
所以上面的正则表达式只成功处理了对应的内容,要继续下去只能针对剩下的频道信息,再写出对应的正则。
4.另一则表达式:- .*subTitle":"(.*?)".*hwurl":"(.*?)".*zteurl":"(.*?)".*
复制代码
为了向第一次替换的格式对齐,则替换为:
,这样就可以保持中兴源排第一,华为源排第二了,
这样处理后的格式就统一了。有点强迫症
5.最后还发现有四个频道只有单源,湛江的两个频道是华为源,
汕尾的频道是中兴源,所以会出现下面的情况,只要手动把多出来的#号删掉就可以了。
湛江电视台综合频道,#rtp://239.10.0.105:1025
湛江电视台公共频道,#rtp://239.10.0.106:1025
汕尾1测试,rtp://239.20.0.23:3312#
汕尾2测试,rtp://239.20.0.22:3316#
########################################################################
继续更新
原帖子:https://www.right.com.cn/forum/thread-581544-1-1.html
搞了三天终于抓到直播包,请求大神怎么转换为m3u
网上各种Notepad++正则替换都不成功
<script>
//获取频道总数,写入机顶盒内存
var iRet = Authentication.CTCSetConfig ('ChannelCount','314');
</script>
<script>
var iRet;
iRet = Authentication.CTCSetConfig ('Channel','ChannelID="2621",ChannelName="直播室101",UserChannelID="710",ChannelURL="rtsp://183.59.156.50/PLTV/88888888/224/3221226524/00000100000000060000000000018575_0.smil?rrsip=125.88.70.140,rrsip=125.88.104.45&icpid=SSPID&accounttype=1&limitflux=-1&limitdur=-1&accountinfo=:20190426141149,02040249631,218.19.154.5,20190426141149,Umai:CHAN/123222@BESTV.SMG.SMG,C71BE25F35E90B44D0B2CD0BF46734BC,-1,0,1,,,2,,,,2,END",TimeShift="1",TimeShiftLength="7200",ChannelSDP="rtsp://183.59.156.50/PLTV/88888888/224/3221226524/00000100000000060000000000018575_0.smil?rrsip=125.88.70.140,rrsip=125.88.104.45&icpid=SSPID&accounttype=1&limitflux=-1&limitdur=-1&accountinfo=:20190426141149,02040249631,218.19.154.5,20190426141149,Umai:CHAN/123222@BESTV.SMG.SMG,C71BE25F35E90B44D0B2CD0BF46734BC,-1,0,1,,,2,,,,2,END",TimeShiftURL="rtsp://183.59.156.50/PLTV/88888888/224/3221226524/00000100000000060000000000018575_0.smil?rrsip=125.88.70.140,rrsip=125.88.104.45&icpid=SSPID&accounttype=1&limitflux=-1&limitdur=-1&accountinfo=:20190426141149,02040249631,218.19.154.5,20190426141149,Umai:CHAN/123222@BESTV.SMG.SMG,C71BE25F35E90B44D0B2CD0BF46734BC,-1,0,1,,,7,,,,4,END",ChannelType="1",IsHDChannel="2",PreviewEnable="0",ChannelPurchased="0",ChannelLocked="0",ChannelLogURL="",PositionX="0",PositionY="0",BeginTime="0",Interval="0",Lasting="0",ActionType="1",FCCEnable="0",ChannelFECPort="5145"');
</script>
我给出的解决方法:
按照给出的格式,先把无用的行删除掉其它的无用行可以用普通查找模式替换掉(要多执行几次查找替换关键字的操作,操作有点繁杂,替换完之后还要删除空行),
这种操作属于小白的正常操作,想当年我也是用系统自带的笔记本来这样操作的
高级点的操作就是把包含rtsp的行标记出来,通过标签功能删除未标记行就可以了(比较上面的方法简单很多),具体操作如下:
Ctrl+H调出替换功能,选择“标记”标签,查找目标:rtsp,勾选“标记所在行”,查找模式选普通,然后执行查找全部,
这样就能把只含频道内容的行标记出来了,接着 菜单栏→“搜索”→“书签”→“删除未标记行” ,结果其它无关的内容包括空行都消失掉了,这样整个文档就井然有序了。
查找目标:- .*ChannelName="(.*?)".*ChannelURL="(.*?)(\?.*?)".*
复制代码
替换为:
替换后的结果:
#EXTINF:-1,直播室101
rtsp://183.59.156.50/PLTV/88888888/224/3221226524/00000100000000060000000000018575_0.smil
最后把文档另存为m3u就可以了。
########################################################################
继续更新例子
刚刚打开论坛,发现昨天有坛友私信我,求助提取节目源,下面是他给的数据格式:
<script>
var iRet;
iRet = Authentication.CUSetConfig ('Channel','ChannelID="1653",ChannelName="海看教育",UserChannelID="122",ChannelURL="igmp://239.253.254.95:8000",TimeShift="1",TimeShiftLength="10800",ChannelSDP="igmp://239.253.254.95:8000",TimeShiftURL="rtsp://61.156.104.90/PLTV/88888888/224/3221226300/10000100000000060000000000446695_0.smil?rrsip=27.223.126.145&icpid=SSPID&accounttype=1&limitflux=-1&limitdur=-1&accountinfo=:20190505192423,053201560048,10.152.219.116,20190505192423,99081002000000050000000000000305,1B6B6657EF0952469F747A255D5DE086,-1,1,1,,,7,,,,4,END",ChannelType="1",IsHDChannel="2",PreviewEnable="1",ChannelPurchased="1",ChannelLocked="0",ChannelLogURL="http://61.156.104.101:33200/EPG/jsp/images/universal/film/logo/iptvcms/webapps/cms/upload/poster/201607/IMG201607060346044344614_171p176.pppp.jpg",PositionX="0",PositionY="0",BeginTime="0",Interval="0",Lasting="0",ActionType="1",FCCEnable="0",ChannelFECPort="0"');
</script>
上个例子中有提过先把频道信息以外的无用行去掉,步骤大概是先标记需要的行,然后通过书签功能把无用的行删除掉,就能把有用的行筛选出来了。这里就不详说了,不懂的参考上面的例子。
筛选后的内容:
iRet = Authentication.CUSetConfig ('Channel','ChannelID="1653",ChannelName="海看教育",UserChannelID="122",ChannelURL="igmp://239.253.254.95:8000",TimeShift="1",TimeShiftLength="10800",ChannelSDP="igmp://239.253.254.95:8000",TimeShiftURL="rtsp://61.156.104.90/PLTV/88888888/224/3221226300/10000100000000060000000000446695_0.smil?rrsip=27.223.126.145&icpid=SSPID&accounttype=1&limitflux=-1&limitdur=-1&accountinfo=:20190505192423,053201560048,10.152.219.116,20190505192423,99081002000000050000000000000305,1B6B6657EF0952469F747A255D5DE086,-1,1,1,,,7,,,,4,END",ChannelType="1",IsHDChannel="2",PreviewEnable="1",ChannelPurchased="1",ChannelLocked="0",ChannelLogURL="http://61.156.104.101:33200/EPG/jsp/images/universal/film/logo/iptvcms/webapps/cms/upload/poster/201607/IMG201607060346044344614_171p176.pppp.jpg",PositionX="0",PositionY="0",BeginTime="0",Interval="0",Lasting="0",ActionType="1",FCCEnable="0",ChannelFECPort="0"');
由于那位坛友没有说明想要哪种格式,我就先写出一个针对这个例子的公用查找目标,然后通过替换不同的替换条件来提取不同的格式。
公用查找目标:- .*ChannelName="(.*?)".*ChannelURL="(.*?:)(.*?)".*TimeShiftURL="(.*?)(\?.*?)".*
复制代码
替换为:
替换结果:
#EXTINF:-1,海看教育
rtp://239.253.254.95:8000
替换为:
替换后不带参数的结果:
#EXTINF:-1,海看教育
rtsp://61.156.104.90/PLTV/88888888/224/3221226300/10000100000000060000000000446695_0.smil
替换为:
替换后带参数的结果:
#EXTINF:-1,海看教育
rtsp://61.156.104.90/PLTV/88888888/224/3221226300/10000100000000060000000000446695_0.smil?rrsip=27.223.126.145&icpid=SSPID&accounttype=1&limitflux=-1&limitdur=-1&accountinfo=:20190505192423,053201560048,10.152.219.116,20190505192423,99081002000000050000000000000305,1B6B6657EF0952469F747A255D5DE086,-1,1,1,,,7,,,,4,END
上面的替换结果另存为m3u文件,就可以得到m3u格式的播放列表文件,给支持m3u格式的播放器使用了。
下面的替换结果保存为txt文件,就可以直接给超级直播、HDP、新世纪、零号播放器等支持txt格式的播放软件使用了。
替换为:
替换结果:海看教育,rtp://239.253.254.95:8000
替换为:
替换后不带参数的结果:海看教育,rtsp://61.156.104.90/PLTV/888888 ... 000000446695_0.smil
替换为:
替换后带参数的结果:
海看教育,rtsp://61.156.104.90/PLTV/888888 ... nfo=:20190505192423,053201560048,10.152.219.116,20190505192423,99081002000000050000000000000305,1B6B6657EF0952469F747A255D5DE086,-1,1,1,,,7,,,,4,END
就这样可以得到各种不同的格式结果了。
########################################################################
20190529更新
说来真的惭愧,一直以来我都以为Notepad++的正则表达式只能单行匹配,所以这个帖子上面给出的例子都是以单行匹配为思路写的,但是到今天我才发现Notepad++其实正则表达式是可以多行匹配的。
今天发现这个帖子:https://www.right.com.cn/forum/thread-248691-1-5.html ,看到了8楼的@鲲翔坛友回复的表达式
- .+?<script>.+?ChannelName="(.+?)",.+?ChannelURL="(.+?\?).+?</script>
复制代码 一看这则表达式是从<script>开始匹配到</script>结束的,而从<script>到</script>之间总共是4行内容,所以说这表达式是针对多行进行匹配的,但按照我以前的操作会出现错误提示
然后经过一番研究发现只要把“匹配新行”勾选上就可以
但是我对按照这个表达式替换的结果不太满意,在播放地址的尾巴上都留下了?号,所以我把这个表达式修改成
- .+?<script>.+?ChannelName="(.+?)",.+?ChannelURL="(.+?)(\?.+?)".+?</script>
复制代码
结果如下图,播放地址后的?号尾巴就不见了
这个表达式跟上面的表达式效果一样,只不过是把+号换成*号罢了,大家可以根据自己的喜好的风格来选择
- .*?<script>.*?ChannelName="(.*?)",.*?ChannelURL="(.*?)(\?.*?)".*?</script>
复制代码
我以前确实对表达式不太了解,写出来的正则表达式也很一般,但是大家从这个帖子的第一个例子往下看,会发现我写的正则表达式也一直在进步和优化,
这是因为我通过不断的练习,对正则表达式越来越熟悉了,所以大家如果想要掌握正则表达式就要多多练习,说一万遍不如自己亲自做一遍,有兴趣的朋友就来下载练习附件自己练习吧!
########################################################################
其实不同的地方或者不同的网络,抓到的数据包的格式都可能是千变万化的,不存在一条正则表达式就可以吃遍天下的可能的,所以学正则表达式一定要灵活应用,生搬硬套只会处处碰壁。
最后,希望能对大家了解和学习正则表达式有所帮助吧!
可以的话请各位朋友给我加加分,希望能够快点升级,解锁更高的阅读权限。
|