Обнаружение URL-адресов в тексте с помощью JavaScript
есть ли у кого-нибудь предложения по обнаружению URL-адресов в наборе строк?
arrayOfStrings.forEach(function(string){
// detect URLs in strings and do something swell,
// like creating elements with links.
});
обновление: Я закончил использовать это регулярное выражение для обнаружения ссылок ... по-видимому, несколько лет спустя.
kLINK_DETECTION_REGEX = /(([a-z]+://)?(([a-z0-9-]+.)+([a-z]{2}|aero|arpa|biz|com|coop|edu|gov|info|int|jobs|mil|museum|name|nato|net|org|pro|travel|local|internal))(:[0-9]{1,5})?(/[a-z0-9_-.~]+)*(/([a-z0-9_-.]*)(?[a-z0-9+_-.%=&]*)?)?(#[a-zA-Z0-9!$&'()*+.=-_~:@/?]*)?)(s+|$)/gi
полный помощник (с дополнительной поддержкой руля) находится в gist #1654670.
8 ответов:
сначала вам нужно хорошее регулярное выражение, которое соответствует url. Это трудно сделать. Смотрите здесь,здесь и здесь:
...почти все, что является допустимым URL. Там некоторые правила пунктуации для разбивая его. Отсутствуют какие-либо пунктуация, вы все еще действительны URL-АДРЕС.
проверьте RFC тщательно и посмотреть, если вы можно построить "недопустимый" URL. Этот правила очень гибкие.
для пример
:::::является допустимым URL. Путь-это":::::". Довольно глупое имя файла, но допустимое имя файла.и
/////является допустимым URL. Этот netloc ("имя хоста") - это"". Путь это"///". Опять же, глупо. Также действительный. Этот URL-адрес нормализуется до"///"что является эквивалентом.что-то вроде
"bad://///worse/////"это совершенно справедливо. Тупой, но действительный.в любом случае, этот ответ не предназначен, чтобы дать вам лучшее регулярное выражение, но скорее доказательство того, как сделать обертку строки внутри текста, с помощью JavaScript.
хорошо, так что давайте просто использовать этот:
/(https?:\/\/[^\s]+)/gопять это плохое выражение. Он будет иметь много ложных срабатываний. Однако это достаточно хорошо для этого примера.
function urlify(text) { var urlRegex = /(https?:\/\/[^\s]+)/g; return text.replace(urlRegex, function(url) { return '<a href="' + url + '">' + url + '</a>'; }) // or alternatively // return text.replace(urlRegex, '<a href=""></a>') } var text = "Find me at http://www.example.com and also at http://stackoverflow.com"; var html = urlify(text); // html now looks like: // "Find me at <a href="http://www.example.com">http://www.example.com</a> and also at <a href="http://stackoverflow.com">http://stackoverflow.com</a>"Итак, в сумме попробуйте:
$$('#pad dl dd').each(function(element) { element.innerHTML = urlify(element.innerHTML); });
вот что я в конечном итоге использовал в качестве своего регулярного выражения:
var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig;это не включает конечную пунктуацию в URL. Функция полумесяца работает как шарм :) Итак:
function linkify(text) { var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; return text.replace(urlRegex, function(url) { return '<a href="' + url + '">' + url + '</a>'; }); }
я гуглил эту проблему довольно долго, затем мне пришло в голову, что есть метод Android, android.текст.утиль.Linkify, который использует некоторые довольно надежные регулярные выражения для достижения этой цели. К счастью, Android является открытым исходным кодом.
Они используют несколько различных моделей для сопоставления различных типов URL-адресов. Вы можете найти их все здесь: http://grepcode.com/file/repository.grepcode.com/java/ext/com.google.android/android/2.0_r1/android/text/util/Regex.java#Regex.0WEB_URL_PATTERN
Если вы просто обеспокоены url, которые соответствуют WEB_URL_PATTERN, то есть URL, которые соответствуют спецификации RFC 1738, вы можете использовать это:
/((?:(http|https|Http|Https|rtsp|Rtsp):\/\/(?:(?:[a-zA-Z0-9$\-\_\.\+\!\*\'\(\)\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,64}(?:\:(?:[a-zA-Z0-9$\-\_\.\+\!\*\'\(\)\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,25})?\@)?)?((?:(?:[a-zA-Z0-9][a-zA-Z0-9\-]{0,64}\.)+(?:(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])|(?:biz|b[abdefghijmnorstvwyz])|(?:cat|com|coop|c[acdfghiklmnoruvxyz])|d[ejkmoz]|(?:edu|e[cegrstu])|f[ijkmor]|(?:gov|g[abdefghilmnpqrstuwy])|h[kmnrtu]|(?:info|int|i[delmnoqrst])|(?:jobs|j[emop])|k[eghimnrwyz]|l[abcikrstuvy]|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])|(?:name|net|n[acefgilopruz])|(?:org|om)|(?:pro|p[aefghklmnrstwy])|qa|r[eouw]|s[abcdeghijklmnortuvyz]|(?:tel|travel|t[cdfghjklmnoprtvwz])|u[agkmsyz]|v[aceginu]|w[fs]|y[etu]|z[amw]))|(?:(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}|[1-9][0-9]|[0-9])))(?:\:\d{1,5})?)(\/(?:(?:[a-zA-Z0-9\;\/\?\:\@\&\=\#\~\-\.\+\!\*\'\(\)\,\_])|(?:\%[a-fA-F0-9]{2}))*)?(?:\b|$)/gi;вот полный текст Источник:
"((?:(http|https|Http|Https|rtsp|Rtsp):\/\/(?:(?:[a-zA-Z0-9\$\-\_\.\+\!\*\'\(\)" + "\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,64}(?:\:(?:[a-zA-Z0-9\$\-\_" + "\.\+\!\*\'\(\)\,\;\?\&\=]|(?:\%[a-fA-F0-9]{2})){1,25})?\@)?)?" + "((?:(?:[a-zA-Z0-9][a-zA-Z0-9\-]{0,64}\.)+" // named host + "(?:" // plus top level domain + "(?:aero|arpa|asia|a[cdefgilmnoqrstuwxz])" + "|(?:biz|b[abdefghijmnorstvwyz])" + "|(?:cat|com|coop|c[acdfghiklmnoruvxyz])" + "|d[ejkmoz]" + "|(?:edu|e[cegrstu])" + "|f[ijkmor]" + "|(?:gov|g[abdefghilmnpqrstuwy])" + "|h[kmnrtu]" + "|(?:info|int|i[delmnoqrst])" + "|(?:jobs|j[emop])" + "|k[eghimnrwyz]" + "|l[abcikrstuvy]" + "|(?:mil|mobi|museum|m[acdghklmnopqrstuvwxyz])" + "|(?:name|net|n[acefgilopruz])" + "|(?:org|om)" + "|(?:pro|p[aefghklmnrstwy])" + "|qa" + "|r[eouw]" + "|s[abcdeghijklmnortuvyz]" + "|(?:tel|travel|t[cdfghjklmnoprtvwz])" + "|u[agkmsyz]" + "|v[aceginu]" + "|w[fs]" + "|y[etu]" + "|z[amw]))" + "|(?:(?:25[0-5]|2[0-4]" // or ip address + "[0-9]|[0-1][0-9]{2}|[1-9][0-9]|[1-9])\.(?:25[0-5]|2[0-4][0-9]" + "|[0-1][0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1]" + "[0-9]{2}|[1-9][0-9]|[1-9]|0)\.(?:25[0-5]|2[0-4][0-9]|[0-1][0-9]{2}" + "|[1-9][0-9]|[0-9])))" + "(?:\:\d{1,5})?)" // plus option port number + "(\/(?:(?:[a-zA-Z0-9\;\/\?\:\@\&\=\#\~" // plus option query params + "\-\.\+\!\*\'\(\)\,\_])|(?:\%[a-fA-F0-9]{2}))*)?" + "(?:\b|$)";Если вы хотите быть действительно фантазии, вы можете проверить для адресов электронной почты, а также. Регулярное выражение для адреса электронной почты:
/[a-zA-Z0-9\+\.\_\%\-]{1,256}\@[a-zA-Z0-9][a-zA-Z0-9\-]{0,64}(\.[a-zA-Z0-9][a-zA-Z0-9\-]{0,25})+/giPS: домены верхнего уровня, поддерживаемые вышеуказанным регулярным выражением, актуальны по состоянию на июнь 2007 года. Для получения обновленного списка вам нужно будет проверить https://data.iana.org/TLD/tlds-alpha-by-domain.txt.
на основе Свежие Полумесяца ответ
Если вы хотите обнаружить ссылки С http:// или без http: / / и по www. вы можете использовать следующие
function urlify(text) { var urlRegex = /(((https?:\/\/)|(www\.))[^\s]+)/g; //var urlRegex = /(https?:\/\/[^\s]+)/g; return text.replace(urlRegex, function(url,b,c) { var url2 = (c == 'www.') ? 'http://' +url : url; return '<a href="' +url2+ '" target="_blank">' + url + '</a>'; }) }
функция может быть дополнительно улучшена для визуализации изображений, а также:
function renderHTML(text) { var rawText = strip(text) var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; return rawText.replace(urlRegex, function(url) { if ( ( url.indexOf(".jpg") > 0 ) || ( url.indexOf(".png") > 0 ) || ( url.indexOf(".gif") > 0 ) ) { return '<img src="' + url + '">' + '<br/>' } else { return '<a href="' + url + '">' + url + '</a>' + '<br/>' } }) }или для миниатюрного изображения, которое ссылается на изображение размера fiull:
return '<a href="' + url + '"><img style="width: 100px; border: 0px; -moz-border-radius: 5px; border-radius: 5px;" src="' + url + '">' + '</a>' + '<br/>'а вот функция strip (), которая предварительно обрабатывает текстовую строку для единообразия, удаляя любой существующий html.
function strip(html) { var tmp = document.createElement("DIV"); tmp.innerHTML = html; var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; return tmp.innerText.replace(urlRegex, function(url) { return '\n' + url }) }
эта библиотека на NPM выглядит довольно всеобъемлющей https://www.npmjs.com/package/linkifyjs
Linkify-это небольшой, но всеобъемлющий плагин JavaScript для поиска URL-адресов в обычном тексте и преобразования их в ссылки HTML. Он работает со всеми допустимыми URL-адресами и адресами электронной почты.
tmp.внутренний текст не определен. Вы должны использовать tmp.innerHTML
function strip(html) { var tmp = document.createElement("DIV"); tmp.innerHTML = html; var urlRegex =/(\b(https?|ftp|file):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/ig; return tmp.innerHTML .replace(urlRegex, function(url) { return '\n' + url })
попробуйте это:
function isUrl(s) { if (!isUrl.rx_url) { // taken from https://gist.github.com/dperini/729294 isUrl.rx_url=/^(?:(?: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; // valid prefixes isUrl.prefixes=['http:\/\/', 'https:\/\/', 'ftp:\/\/', 'www.']; // taken from https://w3techs.com/technologies/overview/top_level_domain/all isUrl.domains=['com','ru','net','org','de','jp','uk','br','pl','in','it','fr','au','info','nl','ir','cn','es','cz','kr','ua','ca','eu','biz','za','gr','co','ro','se','tw','mx','vn','tr','ch','hu','at','be','dk','tv','me','ar','no','us','sk','xyz','fi','id','cl','by','nz','il','ie','pt','kz','io','my','lt','hk','cc','sg','edu','pk','su','bg','th','top','lv','hr','pe','club','rs','ae','az','si','ph','pro','ng','tk','ee','asia','mobi']; } if (!isUrl.rx_url.test(s)) return false; for (let i=0; i<isUrl.prefixes.length; i++) if (s.startsWith(isUrl.prefixes[i])) return true; for (let i=0; i<isUrl.domains.length; i++) if (s.endsWith('.'+isUrl.domains[i]) || s.includes('.'+isUrl.domains[i]+'\/') ||s.includes('.'+isUrl.domains[i]+'?')) return true; return false; } function isEmail(s) { if (!isEmail.rx_email) { // taken from http://stackoverflow.com/a/16016476/460084 var sQtext = '[^\x0d\x22\x5c\x80-\xff]'; var sDtext = '[^\x0d\x5b-\x5d\x80-\xff]'; var sAtom = '[^\x00-\x20\x22\x28\x29\x2c\x2e\x3a-\x3c\x3e\x40\x5b-\x5d\x7f-\xff]+'; var sQuotedPair = '\x5c[\x00-\x7f]'; var sDomainLiteral = '\x5b(' + sDtext + '|' + sQuotedPair + ')*\x5d'; var sQuotedString = '\x22(' + sQtext + '|' + sQuotedPair + ')*\x22'; var sDomain_ref = sAtom; var sSubDomain = '(' + sDomain_ref + '|' + sDomainLiteral + ')'; var sWord = '(' + sAtom + '|' + sQuotedString + ')'; var sDomain = sSubDomain + '(\x2e' + sSubDomain + ')*'; var sLocalPart = sWord + '(\x2e' + sWord + ')*'; var sAddrSpec = sLocalPart + '\x40' + sDomain; // complete RFC822 email address spec var sValidEmail = '^' + sAddrSpec + '$'; // as whole string isEmail.rx_email = new RegExp(sValidEmail); } return isEmail.rx_email.test(s); }также распознает URL-адреса, такие как
google.com,http://www.google.bla,http://google.bla,www.google.blaа неgoogle.bla
Comments