使用单一Ruby正则表达式提取不同URL中的Facebook视频ID
嘿,我来帮你搞定用Ruby正则提取Facebook视频ID的问题!
用单一Ruby正则提取Facebook视频ID
首先得梳理下常见的Facebook视频URL格式,毕竟不同场景下的链接结构差异不小:
- 个人主页视频链接:
https://www.facebook.com/john.doe/videos/123456789012345/ - 官方watch页面链接:
https://www.facebook.com/watch/?v=123456789012345 - fb.watch短链:
https://fb.watch/abc123XYZ/ - 嵌入用的插件链接:
https://www.facebook.com/plugins/video.php?href=https%3A%2F%2Fwww.facebook.com%2Fjohn.doe%2Fvideos%2F112233445566778%2F
下面这个Ruby正则可以一次性覆盖所有这些场景,还能处理大小写、末尾斜杠等细节:
fb_video_regex = %r{ # 匹配两种URL前缀(非捕获组,不提取前缀内容) (?:facebook\.com\/(?:[^\/]+\/videos|watch)\S*[?&]v=|fb\.watch\/) # 捕获视频ID:支持数字+字母的形式(兼容长视频ID和短链ID) ([a-zA-Z0-9]+) # 匹配ID后的结束标记(斜杠、参数分隔符或字符串结尾) (?:\/|\?|&|$) }ix
正则细节解释
%r{...}ix:用Ruby的%r语法定义正则,避免频繁转义斜杠;i修饰符忽略URL大小写(比如FACEBOOK.COM也能匹配),x修饰符允许正则里加空格和注释,可读性更强- 前缀匹配部分:区分facebook主站的视频路径(个人主页视频/官方watch页)和fb.watch短链两种情况
- 捕获组
([a-zA-Z0-9]+):精准提取视频ID,不管是长串数字还是短链的字母数字混合ID - 结尾匹配:确保不会把ID后面的参数、斜杠误当成ID的一部分
实际使用示例
# 测试用的各种Facebook视频URL test_urls = [ "https://www.facebook.com/john.doe/videos/123456789012345/", "https://FACEBOOK.com/watch/?v=987654321098765&foo=bar", "https://fb.watch/abc123XYZ/", "https://www.facebook.com/plugins/video.php?href=https%3A%2F%2Fwww.facebook.com%2Fjohn.doe%2Fvideos%2F112233445566778%2F", "https://www.facebook.com/non-video-page" # 非视频链接,用于测试匹配失败情况 ] test_urls.each do |url| if match_result = url.match(fb_video_regex) puts "提取到视频ID: #{match_result[1]}" else puts "⚠️ 该URL不是Facebook视频链接: #{url}" end end
运行这段代码会输出:
提取到视频ID: 123456789012345 提取到视频ID: 987654321098765 提取到视频ID: abc123XYZ 提取到视频ID: 112233445566778 ⚠️ 该URL不是Facebook视频链接: https://www.facebook.com/non-video-page
为什么你的JS正则转Ruby会出错?
常见的几个坑点:
- 分隔符冲突:JS正则用
/.../包裹,遇到斜杠要转义,而Ruby用%r{...}可以避免这个麻烦,写起来更顺畅 - 修饰符写法:JS把修饰符写在
/.../后面(比如/.../i),Ruby虽然也支持/.../i,但用%r{...}ix更适合复杂正则 - 部分ES新特性不兼容:如果你的JS正则用了ES2018之后的正向断言等特性,Ruby需要调整写法,但Facebook视频URL的正则一般不会涉及这些
如果你的JS正则是类似这样的:
const regex = /(?:facebook\.com\/(?:[^\/]+\/videos|watch)\S*[?&]v=|fb\.watch\/)([a-zA-Z0-9]+)(?:\/|\?|&|$)/i;
转成Ruby只需要改成%r{...}i或者/(?:facebook\.com\/(?:[^\/]+\/videos|watch)\S*[?&]v=|fb\.watch\/)([a-zA-Z0-9]+)(?:\/|\?|&|$)/i就能正常运行啦。
内容的提问来源于stack exchange,提问作者Mathieu
相关产品推荐
相关产品推荐

