جاوااسکریپت - یک عبارت منظم خوب برای مطابقت با یک URL چیست؟


در حال حاضر من یک جعبه ورودی دارم که URL را تشخیص داده و دادهها را تحلیل میکند.

پس در حال حاضر، من از این استفاده میکنم:

var urlR = /^(?:([A-Za-z]+):)?(\/{0,3})([0-9.\-A-Za-z]+)
           (?::(\d+))?(?:\/([^?#]*))?(?:\?([^#]*))?(?:#(.*))?$/;
var url= content.match(urlR);

مشکل این است که وقتی یک URL مثل www.google.com وارد میکنم، کار نمیکند. وقتی http://www.google.com را وارد کردم، کار میکند.

من در عبارات منظم خیلی روان نیستم. آیا کسی میتواند به من کمک کند؟

پاسخ شماره ۱

عبارت منظم اگر میخواهید اطمینان حاصل کنید که URL با HTTP/HTTPS شروع میشود:

https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)

اگر به پروتکل HTTP نیاز ندارید:

[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)

برای امتحان این موضوع، به http://regexr.com?37i6s مراجعه کنید، یا برای نسخهای که محدودکننده کمتری دارد به http://regexr.com/3e6m0 بروید.

نمونه پیادهسازی جاوااسکریپت:

const expression = /[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/gi;
const regex = new RegExp(expression);
const t = 'www.google.com';

if (t.match(regex)) {
  alert("Successful match");
} else {
  alert("No match");
}

پاسخ شماره ۲

(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})

با موارد زیر مطابقت خواهد داشت

  • http://www.foufos.gr
  • https://www.foufos.gr
  • http://foufos.gr
  • http://www.foufos.gr/kino
  • http://werer.gr
  • www.foufos.gr
  • www.mp3.com
  • www.t.co
  • http://t.co
  • http://www.t.co
  • https://www.t.co
  • www.aa.com
  • http://aa.com
  • http://www.aa.com
  • https://www.aa.com
  • badurlnotvalid://www.google.com - captured url www.google.com
  • htpp://www.google.com - captured url www.google.com

با موارد زیر مطابقت نخواهد داشت

  • www.foufos
  • www.foufos-.gr
  • www.-foufos.gr
  • foufos.gr
  • http://www.foufos
  • http://foufos
  • www.mp3#.com

var expression = /(https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|www\.[a-zA-Z0-9][a-zA-Z0-9-]+[a-zA-Z0-9]\.[^\s]{2,}|https?:\/\/(?:www\.|(?!www))[a-zA-Z0-9]+\.[^\s]{2,}|www\.[a-zA-Z0-9]+\.[^\s]{2,})/gi;
var regex = new RegExp(expression);

var check = [
  'http://www.foufos.gr',
  'https://www.foufos.gr',
  'http://foufos.gr',
  'http://www.foufos.gr/kino',
  'http://werer.gr',
  'www.foufos.gr',
  'www.mp3.com',
  'www.t.co',
  'http://t.co',
  'http://www.t.co',
  'https://www.t.co',
  'www.aa.com',
  'http://aa.com',
  'http://www.aa.com',
  'https://www.aa.com',
  'badurlnotvalid://www.google.com',
  'htpp://www.google.com',
  'www.foufos',
  'www.foufos-.gr',
  'www.-foufos.gr',
  'foufos.gr',
  'http://www.foufos',
  'http://foufos',
  'www.mp3#.com'
];

check.forEach(function(entry) {
  let match = entry.match(regex);
  if (match) {
    $("#output").append( "<div style='float:left'>Success: " + entry + "</div><div style='float:right'>Captured url: " + match + "</div><br>" );
  } else {
    $("#output").append( "<div style='float:left'>Fail: " + entry + "</div><br>" );
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div id="output"></div>

با نسخهی جدید در روبولار بررسی کنید

آن را در روبولار بررسی کنید - نسخه قدیمی

آن را در روبولار بررسی کنید - نسخه قدیمی

پاسخ شماره ۳

اینها همان رباتهایی هستند که دنبالشان میگردید. این از validator.js گرفته شده است که کتابخانهای است که واقعاً باید برای انجام این کار از آن استفاده کنید. اما اگر بخواهید خودتان بسازید، من چه کسی هستم که جلوی شما را بگیرم؟ اگر فقط میخواهید از regex خالص استفاده کنید، میتوانید بررسی طول را حذف کنید. به نظرم ایده خوبی است که طول URL را هم تست کنید اگر واقعاً میخواهید تطابق با مشخصات را تعیین کنید.

 function isURL(str) {
     var urlRegex = '^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-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,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$';
     var url = new RegExp(urlRegex, 'i');
     return str.length < 2083 && url.test(str);
}

تست:

function isURL(str) {
         var urlRegex = '^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-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,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$';
         var url = new RegExp(urlRegex, 'i');
         return str.length < 2083 && url.test(str);
    }
var check = [
  'http://www.foufos.gr',
  'https://www.foufos.gr',
  'http://foufos.gr',
  'http://www.foufos.gr/kino',
  'http://werer.gr',
  'www.foufos.gr',
  'www.mp3.com',
  'www.t.co',
  'http://t.co',
  'http://www.t.co',
  'https://www.t.co',
  'www.aa.com',
  'http://aa.com',
  'http://www.aa.com',
  'https://www.aa.com',
  'www.foufos',
  'www.foufos-.gr',
  'www.-foufos.gr',
  'foufos.gr',
  'http://www.foufos',
  'http://foufos',
  'www.mp3#.com'
];

for (let index = 0; index < check.length; index++) {
var url=check[index]
  if  (isURL(check[index]))
    console.log(`${url}         ✔`);
else{
  console.log(`${url}          ❌`);
}
  
}

نتیجه

پاسخ شماره ۴

یک راه حل ممکن دیگر، راه حل بالا در تجزیه پارامترهای رشته پرسوجو برای من شکست خورد.

var regex = new RegExp("^(http[s]?:\\/\\/(www\\.)?|ftp:\\/\\/(www\\.)?|www\\.){1}([0-9A-Za-z-\\.@:%_\+~#=]+)+((\\.[a-zA-Z]{2,3})+)(/(.)*)?(\\?(.)*)?");

if(regex.test("http://google.com")){
  alert("Successful match");
}else{
  alert("No match");
}

در این راهحل لطفاً آزاد باشید [-0-9A-Za-z\.@:%_\+~#= را برای مطابقت با نام دامنه/زیر دامنه اصلاح کنید. در این راهحل پارامترهای رشته پرس و جو نیز مدیریت میشوند.

اگر از RegEx استفاده نمیکنید، از عبارت \\ را با \ جایگزین کنید.

امیدوارم این کمک کند.

تست:-

function IsUrl(url){
    var regex = new RegExp("^(http[s]?:\\/\\/(www\\.)?|ftp:\\/\\/(www\\.)?|www\\.){1}([0-9A-Za-z-\\.@:%_\+~#=]+)+((\\.[a-zA-Z]{2,3})+)(/(.)*)?(\\?(.)*)?");

if(regex.test(url)){
  console.log(`${url}         ✔`);
}else{
  console.log(`${url}          ❌`);
}}
var check = [
  'http://www.foufos.gr',
  'https://www.foufos.gr',
  'http://foufos.gr',
  'http://www.foufos.gr/kino',
  'http://werer.gr',
  'www.foufos.gr',
  'www.mp3.com',
  'www.t.co',
  'http://t.co',
  'http://www.t.co',
  'https://www.t.co',
  'www.aa.com',
  'http://aa.com',
  'http://www.aa.com',
  'https://www.aa.com',
  'www.foufos',
  'www.foufos-.gr',
  'www.-foufos.gr',
  'foufos.gr',
  'http://www.foufos',
  'http://foufos',
  'www.mp3#.com'
];
for (let index = 0; index < check.length; index++) {
    IsUrl(check[index])
}

نتیجه