RegEx用于提取YouTube ID和时间顺序

时间:2019-05-25 15:28:44

标签: regex string regex-lookarounds regex-group regex-greedy

我想从YouTube网址中提取视频ID(字符串)和序列整数(如果有)。

输入

https://www.youtube.com/watch?v=doXt8abo3IY
https://youtu.be/FIqBQ-CxAfQ
http://www.youtube.com/watch?v=MlOSMl33CNA&t=0m4s

我尝试了这种模式,但是它不起作用:

^https?://.*(?:youtu.be/|v/|u/\w/|embed/|watch?v=)([^#&?]*).*$

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

您非常接近,但是您没有正确地逃脱斜线。尽管每种语言可能有所不同,但我不确定。无论如何,这是我得到的有效正则表达式:

^https?:\/\/.*(?:youtu.be\/|v\/|u\/\w\/|embed\/|watch?v=)([^#&?]*).*(?>t=([0-9]+)).*$

有关测试和导出为不同语言的功能,请参见https://regex101.com/r/9EjjN4/1

答案 1 :(得分:0)

如果我们只希望匹配问题中列出的情况,则可以将表达式简化为类似以下内容:

(?:.+v=|.+\.be\/)(.+?)($|&.+)

因为,我猜测我们可能并不是真的想要验证URL。但是,如果我们想添加更多的边界,我们可以这样做。

在这里,我们在一个非捕获组中使用逻辑OR合并了两个条件:

(?:.+v=|.+\.be\/)

然后,我们使用捕获组来收集所需的ID:

(.+?)

最后,我们添加一个右边界:

($|&.+)

这也适用于右边界(使用非捕获组):

(?:$|&.+)

此表达式可能易于修改,如果出现其他任何URL,我们只需在所需ID的左侧和右侧使用逻辑OR来添加新边界。

enter image description here

const regex = /(?:.+v=|.+\.be\/)(.+?)($|&.+)/gm;
const str = `https://www.youtube.com/watch?v=doXt8abo3IY
https://youtu.be/FIqBQ-CxAfQ
http://www.youtube.com/watch?v=MlOSMl33CNA&t=0m4s`;
const subst = `$1`;

// The substituted value will be contained in the result variable
const result = str.replace(regex, subst);

console.log('Substitution result: ', result);

DEMO

RegEx

如果不需要此表达式,可以在regex101.com中对其进行修改或更改。

RegEx电路

jex.im可视化正则表达式:

enter image description here


如果我们希望捕获t变量,则可以扩展表达式,也许可以扩展为类似以下内容:

(?:.+)(?:\.be\/|v=)(.+?)(?:&|$)(?:t=)?(.+)?

如果我们为每个任务设计个性化表达,可能会更好,否则,我们可能会面临未来的问题。例如,如果我们可以为.be设计一个单独的表达式,为v=设计一个单独的表达式,为t=设计一个单独的表达式,那就更好了。

DEMO

const regex = /(?:.+)(?:\.be\/|v=)(.+?)(?:&|$)(?:t=)?(.+)?/gm;
const str = `https://www.youtube.com/watch?v=doXt8abo3IY
https://youtu.be/FIqBQ-CxAfQ
http://www.youtube.com/watch?v=MlOSMl33CNA&t=0m4s`;
let m;

while ((m = regex.exec(str)) !== null) {
    // This is necessary to avoid infinite loops with zero-width matches
    if (m.index === regex.lastIndex) {
        regex.lastIndex++;
    }
    
    // The result can be accessed through the `m`-variable.
    m.forEach((match, groupIndex) => {
        console.log(`Found match, group ${groupIndex}: ${match}`);
    });
}