正则表达式:还有什么我应该用来实现我想要的吗?

Regex: Is there something else I should be using to achieve what I want?

基于大量搜索示例,我创建了一个正则表达式,我使用它(作为后备)来解析来自 HTML 来源的直接文件 links:

/((?:(?:https?%3A%2F%2F)(?:www\.)?(?:\S+)%2F|(?:https?:\/\/)(?:www\.)?(?:\S+)\/)(?:.*)?\.(mp4|mkv|wmv|m4v|mov|avi|flv|webm|flac|mka|m4a|aac|ogg)(?=[^.]*$))/igm

我的问题是它在包含多个 link 的行上失败。我知道使用正则表达式解析 HTML 即使作为回退也是不受欢迎的,所以我还能用什么来查找页面源中的所有直接文件 link? (这意味着 link 隐藏在内联 JavaScript、视频源标签等中;而不仅仅是 document.links returns。)

如果没有更好的建议,谁能帮我修改正则表达式来实现我想要的?

正则表达式应遵循以下准则:

一些应该匹配的例子:

http://test.com/test.mkv
http://test.com/test/test.jpg.mkv
https://test.com/test.mkv?test=test
http%3A%2F%2Ftest.com%2Ftest.mkv%3Ftest%3Dtest
https%3A%2F%2Ftest.com%2Ftest.jpg.mkv%3Ftest%3Dtest.mkv
http://test.com/t est.mkv__some__random__string__http://test.com/test.mkv

最后一个示例应匹配两个 URL,但不匹配 __some__random__string__

一些不应匹配的示例:

http://test.com/test.mkv.jpg
http://test.com/test.mkv/test.jpg
https://test.com/test.mkv.jpg?test=test.mkv
http%3A%2F%2Ftest.com%2Ftest.mkv.jpg
https%3A%2F%2Ftest.com%2Ftest.mkv.jpg%3Ftest%3Dtest.mkv
http://test.com/t est.mkv__some__random__string__http://test.com/test.mkv.jpg

最后一个例子应该只匹配第一个 URL,在 __some__random__string__.

之前

您可以使用正则表达式和一些 HTML 部分失败的来源示例:http://regexr.com/3dbac

好吧,如果我们只考虑您在此处提供的样本,您可以利用 tempered greedy token (TGT) 来否定您需要匹配的扩展名:

/((?:https?(?:%3A%2F%2F|:\/\/))(?:www\.)?(?:\S+)(?:%2F|\/)(?:(?!\.(?:mp4|mkv|wmv|m4v|mov|avi|flv|webm|flac|mka|m4a|aac|ogg))[^\/])*\.(mp4|mkv|wmv|m4v|mov|avi|flv|webm|flac|mka|m4a|aac|ogg))(?!\/|\.[a-z]{1,3})/

regex demo

模式细分:

(        # Group 1 matching the whole URL
  (?:https?(?:%3A%2F%2F|:\/\/))(?:www\.)?(?:\S+)(?:%2F|\/) # Matching URL part with no spaces up to the last /
  (?:(?!\.(?:mp4|mkv|wmv|m4v|mov|avi|flv|webm|flac|mka|m4a|aac|ogg))[^\/])* # TGT matching up to the extension
  \.(mp4|mkv|wmv|m4v|mov|avi|flv|webm|flac|mka|m4a|aac|ogg) # The extension
)
(?!\/|\.[a-z]{1,3}) # Only if not followed with /, or another extension

(?:(?!\.(?:mp4|mkv|wmv|m4v|mov|avi|flv|webm|flac|mka|m4a|aac|ogg))[^\/])* TGT 匹配除​​ / 之外的任何字符,这些字符不是 .mp4.mkv 等文字字符序列的第一个字符(作为如果否定先行的模式与字符串中当前位置右侧的文本匹配,则匹配失败。