如何检查字符串是否在ReGex中,即使它不完全匹配?

时间:2017-04-29 22:53:23

标签: jquery regex

我有一个网站,人们可以将YouTube链接输入文本框。如果键入的链接是有效YouTube网址的开头,或者如果不是,则我还希望在输入框旁边显示一个勾号图标。使用Jquery我试过这样做:

$(document).ready(function(){
$("#yt_input").keyup(function(){
    var link = $(this).val();
    var p = /(?:https?:\/\/)?(?:www\.)?((youtu.be|youtube\.com)\/(watch\?v=)).{10,13}$/;
    if(link.match(p)  !== null){
        $("#yt_input_status").attr("src", "tick_icon.png");
    } else {
        $("#yt_input_status").attr("src", "cross_icon.png");
    }
});


});

这样可以正常工作,但只有在输入了整个(有效)网址时才有效。例如,如果用户输入https这是有效网址的开头https://www.youtube.com/watch?v=jsidR6kBZ6A此交叉图标将出现,在给出整个链接之前不要更改。我不确定这是否仅仅是将RegEx修改为诸如“按特定顺序中的任何这些字符”之类的内容,或者是否存在类似于支持RegEx的.contains()的jquery函数。有没有办法做到这一点?
非常感谢任何帮助!

1 个答案:

答案 0 :(得分:1)

这不是一个明智的想法,因为你基本上显示了一个无效的链接,好像它正常工作一样,而且在实时匹配时也会给你带来很多麻烦。

因此,如果您需要,这里有一个更好的解决方案:您可以测试当前字符串是否实际上是一个URL,而如果不是,则显示一个加载图标,例如:{{3} },如果您尝试匹配的文本实际上是一个URL,那么您需要做的就是匹配。
根据Type a valid URL to identify...答案,您可以使用以下函数进行测试:

function isURL(value) {
  return /^(?:(?:(?:https?|ftp):)?\/\/)(?:\S+(?::\S*)?@)?(?:(?!(?:10|127)(?:\.\d{1,3}){3})(?!(?:169\.254|192\.168)(?:\.\d{1,3}){2})(?!172\.(?:1[6-9]|2\d|3[0-1])(?:\.\d{1,3}){2})(?:[1-9]\d?|1\d\d|2[01]\d|22[0-3])(?:\.(?:1?\d{1,2}|2[0-4]\d|25[0-5])){2}(?:\.(?:[1-9]\d?|1\d\d|2[0-4]\d|25[0-4]))|(?:(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)(?:\.(?:[a-z\u00a1-\uffff0-9]-*)*[a-z\u00a1-\uffff0-9]+)*(?:\.(?:[a-z\u00a1-\uffff]{2,})).?)(?::\d{2,5})?(?:[/?#]\S*)?$/i.test(value);
}

然后,如果所需的文字不是网址,您可以只显示另一个图标。

示例结果

if (isURL(link)){
    if(link.match(p) !== null){
        $("#yt_input_status").attr("src", "tick_icon.png");
    } else {
        $("#yt_input_status").attr("src", "cross_icon.png");
    }
} else {
    $("#yt_input_status").attr("src", "waiting_icon.gif"); //Example icon
}

但是如果你真的想要获得一个tick_icon,而它不是一个有效的URL,你可以使用正则表达式来部分匹配它。 this威胁为您提供了将正则表达式转换为部分匹配正则表达式的功能 输入:

/(?:https?:\/\/)?(?:www\.)?((youtu.be|youtube\.com)\/(watch\?v=)).{10,13}$/.toPartialMatchRegex();

输出:

/(?:(?:h|$)(?:t|$)(?:t|$)(?:p|$)(?:s|$)?(?::|$)(?:\/|$)(?:\/|$)|$)?(?:(?:w|$)(?:w|$)(?:w|$)(?:\.|$)|$)?(((?:y|$)(?:o|$)(?:u|$)(?:t|$)(?:u|$)(?:.|$)(?:b|$)(?:e|$)|(?:y|$)(?:o|$)(?:u|$)(?:t|$)(?:u|$)(?:b|$)(?:e|$)(?:\.|$)(?:c|$)(?:o|$)(?:m|$)|$)(?:\/|$)((?:w|$)(?:a|$)(?:t|$)(?:c|$)(?:h|$)(?:\?|$)(?:v|$)(?:=|$)|$)|$)(?:.|$){10,13}$/

最终结果

var partialp = /(?:(?:h|$)(?:t|$)(?:t|$)(?:p|$)(?:s|$)?(?::|$)(?:\/|$)(?:\/|$)|$)?(?:(?:w|$)(?:w|$)(?:w|$)(?:\.|$)|$)?(((?:y|$)(?:o|$)(?:u|$)(?:t|$)(?:u|$)(?:.|$)(?:b|$)(?:e|$)|(?:y|$)(?:o|$)(?:u|$)(?:t|$)(?:u|$)(?:b|$)(?:e|$)(?:\.|$)(?:c|$)(?:o|$)(?:m|$)|$)(?:\/|$)((?:w|$)(?:a|$)(?:t|$)(?:c|$)(?:h|$)(?:\?|$)(?:v|$)(?:=|$)|$)|$)(?:.|$){10,13}$/;
var p = /(?:https?:\/\/)?(?:www\.)?((youtu.be|youtube\.com)\/(watch\?v=)).{10,13}$/;
if (!link.includes("youtu")) {
    if(link.match(partialp) !== null){
        $("#yt_input_status").attr("src", "tick_icon.png");
    } else {
        $("#yt_input_status").attr("src", "cross_icon.png");
    }
} else {
    if(link.match(p) !== null){
        $("#yt_input_status").attr("src", "tick_icon.png");
    } else {
        $("#yt_input_status").attr("src", "cross_icon.png");
    }
}

顺便说一句,这种测试方式的问题在于,有时它可能不符合您的预期,因为它部分测试了URL并仅测试了最后一个字符,总是......您可能会发现它无法与https://www.youtube.com/watch?=ew一起使用,因为最后的w与来自w的{​​{1}}匹配。这就是为什么第一种选择更可取的原因。

您的正则表达式的一些注意事项:  
- 您的正则表达式似乎与www.匹配,后者是有效的YouTube网址,因为它会重定向到youtu.be/watch?v=BFxqR7EO8ho。  
- 此外,它不会将视频与This匹配,例如youtube.com/watch?v=watch  
- 也不是其他youtube特殊国家'链接(即https://www.youtube.com/watch?gl=GB&v=BFxqR7EO8ho&feature=youtu.be youtube.com.br/...)。但无论如何,你能吗?    解释这个'无效网址'你打算匹配吗?