Convert plain text links to clickable links - javascript

Long story short, I have a website made under Wix.com editor, and coding was made possible a few months ago.
I have set up a custom comment box, so users can post their comments, and read others'.
Now the thing is, the "comment Input" takes plain text, and whenever a link is posted, it is displayed as plain text, no color, no clickability.
I want a code that 'reads' the list of comments, and convert every text that begins with 'https' or 'http' or 'www' ... orange and clickable (opening in a new tab)
Any solution please ?
Thanks !
I have tried many things such as :
$w('#text95').html =
(/((http:|https:)[^\s]+[\w])/g, '$1').replace;
text95 = the displayed comments (it is a text that repeats itself for as many comments as there are)

It looks like your replace syntax is wrong. Try something like this. I'm pretty sure this will work.
function linkify(inputText) {
var replacedText, replacePattern1, replacePattern2, replacePattern3;
//URLs starting with http://, https://, or ftp://
replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/gim;
replacedText = inputText.replace(replacePattern1, '$1');
//URLs starting with "www." (without // before it, or it'd re-link the ones done above).
replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
replacedText = replacedText.replace(replacePattern2, '$1$2');
//Change email addresses to mailto:: links.
replacePattern3 = /(([a-zA-Z0-9\-\_\.])+#[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
replacedText = replacedText.replace(replacePattern3, '$1');
return replacedText;
}
Calling it with:
$w('#text95').innerHTML = linkify($w('#text95').html);

Here is my answer (improved Version including video links).
See also this Codepen here.
const convertLinks = ( input ) => {
let text = input;
const linksFound = text.match( /(?:www|https?)[^\s]+/g );
const aLink = [];
if ( linksFound != null ) {
for ( let i=0; i<linksFound.length; i++ ) {
let replace = linksFound[i];
if ( !( linksFound[i].match( /(http(s?)):\/\// ) ) ) { replace = 'http://' + linksFound[i] }
let linkText = replace.split( '/' )[2];
if ( linkText.substring( 0, 3 ) == 'www' ) { linkText = linkText.replace( 'www.', '' ) }
if ( linkText.match( /youtu/ ) ) {
let youtubeID = replace.split( '/' ).slice(-1)[0];
aLink.push( '<div class="video-wrapper"><iframe src="https://www.youtube.com/embed/' + youtubeID + '" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></div>' )
}
else if ( linkText.match( /vimeo/ ) ) {
let vimeoID = replace.split( '/' ).slice(-1)[0];
aLink.push( '<div class="video-wrapper"><iframe src="https://player.vimeo.com/video/' + vimeoID + '" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe></div>' )
}
else {
aLink.push( '' + linkText + '' );
}
text = text.split( linksFound[i] ).map(item => { return aLink[i].includes('iframe') ? item.trim() : item } ).join( aLink[i] );
}
return text;
}
else {
return input;
}
}
This replaces long and clumsy links within plain texts to short clickable links within that text. (And also wraps videos in responsive iframes)
Example:
This clumsy link https://stackoverflow.com/questions/49634850/javascript-convert-plain-text-links-to-clickable-links/52544985#52544985 is very clumsy and this http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/split is not much better. This one www.apple.com is nice but www can be removed.
Becomes:
This clumsy link stackoverflow.com is very clumsy and this developer.mozilla.org is not much better. This one apple.com is nice but www can be removed.
The linkified text then displays as follows:
This clumsy link stackoverflow.com is very clumsy and this developer.mozilla.org is not much better. This one apple.com is nice but www can be removed.

I'm not sure what $w is or if you can really assign the html like that, but i'm guessing this is jquery since the $ most commonly refers to the jquery object.
Your try was close, it would be..
$('#text95').html($('#text95').html().replace(/((http:|https:)[^\s]+[\w])/g, '$1'));
try it..
$('#text95').html($('#text95').html().replace(/((http:|https:)[^\s]+[\w])/g, '$1'));
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id=text95>
stuff and stuff and http://ww.stuff.com stuff
</div>

I really like the solution by #philipeachille. It’s lightweight and does the essentials. However, it has a couple of issues I needed to address:
if a link is followed immediately by a punctuation mark, the punctuation is included in the link
if the same link is included more than once, the logic gets confused
some links don’t start with either www or http, for example microsoft.com
I derived the following from his code, fixing these issues and omitting the video embedding stuff, which I didn’t want:
const linkify = t => {
const isValidHttpUrl = s => {
let u
try {u = new URL(s)}
catch (_) {return false}
return u.protocol.startsWith("http")
}
const m = t.match(/(?<=\s|^)[a-zA-Z0-9-:/]+\.[a-zA-Z0-9-].+?(?=[.,;:?!-]?(?:\s|$))/g)
if (!m) return t
const a = []
m.forEach(x => {
const [t1, ...t2] = t.split(x)
a.push(t1)
t = t2.join(x)
const y = (!(x.match(/:\/\//)) ? 'https://' : '') + x
if (isNaN(x) && isValidHttpUrl(y))
a.push('' + y.split('/')[2] + '')
else
a.push(x)
})
a.push(t)
return a.join('')
}
To explain the main regular expression:
(?<=\s|^) looks behind (before) the link to determine where the link starts, which is either any white space or the beginning of the string
[a-zA-Z0-9-:/]+\.[a-zA-Z0-9] matches the start of a link – a pattern like xxx.x or even xxx://xxx.x
[a-zA-Z0-9-:/]+ a combination of one or more letters, numbers, hyphens, colons or slashes
\. followed immediately by a dot
[a-zA-Z0-9] followed immediately by another letter or number
.+? matches the rest of the link.
(?=[.,;:?!-]?(?:\s|$)) looks ahead (after) the link to determine where the link ends
?= positive lookahead
(?:\s|$) the link is ended either by any white space or by the end of the string
[.,;:?!-]? unless the white space or end of string is immediately preceded by one of these seven punctuation marks, in which case this punctuation mark ends the link.
Here is a snippet if you’d like to try some different blocks of text to see how they get linkified:
const linkify = t => {
const isValidHttpUrl = s => {
let u
try {u = new URL(s)}
catch (_) {return false}
return u.protocol.startsWith("http")
}
const m = t.match(/(?<=\s|^)[a-zA-Z0-9-:/]+\.[a-zA-Z0-9-].+?(?=[.,;:?!-]?(?:\s|$))/g)
if (!m) return t
const a = []
m.forEach(x => {
const [t1, ...t2] = t.split(x)
a.push(t1)
t = t2.join(x)
const y = (!(x.match(/:\/\//)) ? 'https://' : '') + x
if (isNaN(x) && isValidHttpUrl(y))
a.push('' + y.split('/')[2] + '')
else
a.push(x)
})
a.push(t)
return a.join('')
}
document.querySelectorAll('.linkify-this').forEach(o => {
o.innerHTML = linkify(o.innerHTML)
})
<p class="linkify-this">
Any links I put into this paragraph will be linkified, such as apple.com, http://google.com and www.facebook.com.
</p>
<p class="linkify-this">
https://microsoft.com will be matched even at the start of the text.
</p>
<p class="linkify-this">
If I refer to a domain name suffix only, such as .com or .co.uk, it won't be linkified, only complete domain names like https://www.gov.uk will be linkified.
</p>
<p class="linkify-this">
Some links contain numbers, like w3.org, but we don't want straight decimal numbers like 2.25 to be linkified. We also want to ignore non-http URLs like ftp://some.host.com and injection attempts like https://x.com"style="color:red".
</p>
Update
Following the comment from #newbie.user88 about the lack of injection protection, I thought it wise to add validation of each potential URL by attempting to construct a URL object with it. Credit to #pavlo for the logic.

I correct errors philipeachille's code because youtubeID parameter is not correct. I also correct direct youtube links.
convertLinks = input => {
let text = input;
const aLink = [];
const linksFound = text.match(/(?:www|https?)[^\s]+/g);
if (linksFound != null) {
for (let i = 0; i < linksFound.length; i++) {
let replace = linksFound[i];
if (!(linksFound[i].match(/(http(s?)):\/\//))) {
replace = 'http://' + linksFound[i]
}
let linkText = replace.split('/')[2];
if (linkText.substring(0, 3) == 'www') {
linkText = linkText.replace('www.', '')
}
if (linkText.match(/youtu/)) {
const youtubeID = replace.split('/').slice(-1)[0].split('=')[1];
if (youtubeID === undefined || youtubeID === '') {
aLink.push('' + linkText + '');
} else {
aLink.push('<span class="video-wrapper"><iframe src="https://www.youtube.com/embed/' + youtubeID + '" frameborder="0" allow="accelerometer; autoplay; encrypted-media; gyroscope; picture-in-picture" allowfullscreen></iframe></span>');
}
} else {
aLink.push('' + linkText + '');
}
text = text.split(linksFound[i]).map(item => {
return aLink[i].includes('iframe') ? item.trim() : item
}).join(aLink[i]);
}
return text;
}
else {
return input;
}
};
Usage:
const text = 'Hello. This is a link https://www.google.com and this is youtube video https://www.youtube.com/watch?v=O-hnSlicxV4';
convertLinks(text);

If string contains URL anywhere, convert that string into link.
I try above code but this is not working properly for me. After adding some conditions it worked.
Thank you for helping me out #user9590073
function convertLink(inputText) {
var replacedText, replacePattern1, replacePattern2, replacePattern3;
//URLs starting with http://, https://, or ftp://
replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&#\/%?=~_|!:,.;]*[-A-Z0-9+&#\/%=~_|])/gim;
if (replacePattern1.test(inputText))
inputText = inputText.replace(replacePattern1, '$1');
//URLs starting with "www." (without // before it, or it'd re-link the ones done above).
replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
if (replacePattern2.test(inputText))
inputText = inputText.replace(replacePattern2, '$1$2');
//Change email addresses to mailto:: links.
replacePattern3 = /(([a-zA-Z0-9\-\_\.])+[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
if (replacePattern3.test(inputText))
replacedText = inputText.replace(replacePattern3, '$1');
return inputText;
}
And then I pass my text into ConverLink Func to open my modal with clickable URL.
$modalBody.find('div.news-content').html('<p>' + convertLink(response.NewsContent) + '</p>');

Here is a version (just for http/s and ftp links) that doesn't replace the url with a link if it looks like it's already in a link (or rather that is preceded with a " or ')
function linkifyBareHttp(inputText){
//URLs starting with http://, https://, or ftp://
const replacePattern1 = /\b(?<!(\'|\"))(((https?|ftp):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|]))/gim;
return inputText.replace(replacePattern1, '');
}
here is a little tester, showing what kind of things it handles:
function testLinkify(){
console.log('starting test');
test(`https://example.com`, ``);
test(`\nhttps://example.com`,`\n`);
test(``,``);
test(` https://example.com`,` `);
test(`https://example.com\nhttps://example.net BAZ`,`\n BAZ`);
}
function test(input,expect){
const testFunction = linkifyBareHttp;
const output = testFunction(input);
console.log (output === expect ? 'PASS':'FAIL');
console.log(` INPUT: ${input}`);
if(output !== expect) {
console.log(`EXPECT: ${expect}`);
console.log(`OUTPUT: ${output}`)
}
}

$(".hkt-chat-chatbot-paragraph-msg").map(function() {
$(this).html(linkify($(this).text().replace(/[\u00A0-\u9999<>\&]/g, function(i) { return '&#'+i.charCodeAt(0)+';';})))
});
function linkify(inputText) {
var replacedText, replacePattern1, replacePattern2, replacePattern3;
//URLs starting with http://, https://, or ftp://
replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/gim;
replacedText = inputText.replace(replacePattern1, '$1');
//URLs starting with "www." (without // before it, or it'd re-link the ones done above).
replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim;
replacedText = replacedText.replace(replacePattern2, '$1$2');
//Change email addresses to mailto:: links.
replacePattern3 = /(([a-zA-Z0-9\-\_\.])+#[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim;
replacedText = replacedText.replace(replacePattern3, '$1');
return replacedText;
}
.hkt-chat-chatbot-paragraph-msg{
border:1px solid green;
padding:5px;
margin-bottom:5px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="hkt-chat-chatbot-paragraph-msg" >
www.google.com
https://bing.com
ftp://192.138.1.1:80/home
normal text
paragraph click on next link http://example.com
</div>
<div class="hkt-chat-chatbot-paragraph-msg" >
normal text
</div>
<div class="hkt-chat-chatbot-paragraph-msg" >
www.google.com
https://bing.com
ftp://192.138.1.1:80/home
normal text
paragraph click on next link http://example.com
</div>
This worked for me.
I was having some htmlentity which need to be preserves so first get the text() have converted them first to encoded form and then added hyperlinks and replace the initial text with new html code.

Related

jQuery using Regex to find links within text but exclude if the link is in quotes

I am using jQuery and Regex to search a text string for http or https and convert the string to a URL. I need the code to skip the string if it starts with a quote.
below is my code:
// Get the content
var str = jQuery(this).html();
// Set the regex string
var exp = /(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig;
var replaced_text = str.replace(exp, function(url) {
clean_url = url.replace(/https?:\/\//gi,'');
return '' + clean_url + '';
})
jQuery(this).html(replaced_text);
Here is an example of my issue:
Text The School of Computer Science and Informatics. She blogs at http://www.wordpress.com and can be found on Twitter #Abcdef.
The current code successfully finds the text that starts with http or https and converts it to a URL but it also converts the twitter URL. I need to ignore the text if it starts with a quote or is within an a tag, etc...
Any help is much appreciated
What about adding [^"'] to the exp variable?
var exp = /(\b[^"'](https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig;
Snippet:
// Get the content
var str = jQuery("#text2replace").html();
// Set the regex string
var exp = /(\b[^"'](https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig;
var replaced_text = str.replace(exp, function(url) {
clean_url = url.replace(/https?:\/\//gi,'');
return '' + clean_url + '';
})
jQuery("#text2replace").html(replaced_text);
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="text2replace">
The School of Computer Science and Informatics. She blogs at http://www.wordpress.com and can be found on Twitter #Abcdef.
</div>
If you really just want to ignore the quotation marks, this could help:
var replaced_text = $("#selector").html().replace(/([^"])(\b(https?|ftp|file):\/\/[-A-Z0-9+&##\/%?=~_|!:,.;]*[-A-Z0-9+&##\/%=~_|])/ig, '$1$2');
This works for me:
This will recognize urls and convert them to hyperlinks, but will ignore urls, wrapped in " (quotes).
See the code below or this jsfiddle for a working example.
Example HTML:
<ul class="js-replaceUrls">
<li>
www.link-only-www.com
</li>
<li>
http://link-starts-with-HTTP.com
</li>
<li>
https://www.link-starts-with-https-and-www.com
</li>
<a href="https://link-starts-with-https.com">
Link in anchor tag
</a>
</ul>
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+|$)/gmi
jQuery:
// RECOGNIZE URLS AND CONVERT THEM TO HYPERLINKS
// Ignore if hyperlink is found in HTML attr, like "href"
$('.js-replaceUrls').each(function(){
// GET THE CONTENT
var str = $(this).html();
// SET THE REGEX STRING
var 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+|$)/gmi;
// REPLACE PLAIN TEXT LINKS BY HYPERLINKS
var replaced_text = str.replace(regex, "<a href='$1' class='js-link'>$1</a>");
// ECHO LINK
$(this).html(replaced_text);
});
// DEFINE URLS WITHOUT "http" OR "https"
var linkHasNoHttp = $(".js-link:not([href*=http],[href*=https])");
// ADD "http://" TO "href"
$(linkHasNoHttp).each(function() {
var linkHref = $(this).attr("href");
$(this).attr("href" , "http://" + linkHref);
});
See this jsfiddle for a working example.

RegExp case insensitive multi word highlight

I am trying to get highlighting on keyword searching working right. A couple issues I am having.
Case insensitive is working for the first word, but would like it to replace with original case word, not the lowercase searched word.
i.e. search trend, it replaces Trend with trend, I know why, but would like to figure out how to replace back the found word, not the searched word
The second word is not matching case insensitive.
i.e. search trend micro is not matching trend Micro.
Here is jsFiddle: http://jsfiddle.net/hh2zvjft/1/
if ($(".ProjectSearch").val().length > 0) {
var searchedText = $(".ProjectSearch").val();
var wordList = searchedText.split(" ");
$.each(wordList, function (i, word) {
$(".ProjectTaskGrid:contains('" + word + "')").each(function (i, element) {
var rgxp = new RegExp(word, "gi");
var repl = '<span class="search-found">' + word + '</span>';
element.innerHTML = element.innerHTML.replace(rgxp, repl);
});
});
}
Can you please help identify the issues, and offer improvements? Thanks!
Some refererences used to arrive at code:
https://stackoverflow.com/a/120161/2727155
https://stackoverflow.com/a/10011639/2727155
Highlight multiple words (ignore HTML tags)
const regEscape = str => str.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const EL_input = document.querySelector("#input");
const EL_area = document.querySelector("#area");
const org = EL_area.innerHTML; // Store the current HTML state
const highlight = () => {
const val = EL_input.value;
if (!val) return EL_area.innerHTML = org;
const pts = regEscape(val.trim()).split(/ +/);
const reg = new RegExp("(?![^<]+>)(" + pts.join("|") + ")", "ig");
const res = org.replace(reg, '<span class="highlight">$1</span>');
EL_area.innerHTML = res;
};
EL_input.addEventListener("input", highlight);
highlight();
div {
padding: 5px;
border: solid 1px #CCC;
}
.highlight {
background: gold;
}
<input id="input" autocomplete=off type="text" value="tren pan com br" />
<div id="area">
Renew Trend Worry-Free Business Security license
that someweb.com will expire in 60 days.<br>
Activate BR like breakline trend
and [ confirm <span>SOME <span>SPAN</span> IS HERE</span>
upon electronic<br> delivery notification
from Trend Micro
</div>
You were close! Change line 7 to:
var repl = '<span class="search-found">$&</span>';
Notice the $& in there. It's a reference to the matched word and preserves the case.
http://jsfiddle.net/hh2zvjft/2/
And as Roko pointed out in the comment below, you'll get a constant padding increase of 3px on either side if you keep clicking Find. To fix this I'd recommend removing the padding from the CSS, or disabling the Find button if the words have already been highlighted.

RegExp to ignore everything between <code> and <pre> tags

trying to parse some content (no DOM available - or DOM parser for that matter i.e. jQuery, Cheerio) to replace some words/symbols (basically emotions) by images, BUT would like to ignore everything in between <code></code> and <pre></pre> this example works great on replacing all the emotions, but doesn't ignore code and pre tags
http://jsbin.com/odARehI/5/edit?js,console
if you run the script, you will see the first print out before the code tag and the second after.
would appreciate another set of eyes on that pattern. Thanks
// see link for a list of the emotions to parse
var pattern = />:\)|\([\w~]+\)|\\[:]?[od]\/|[:;\|bBiIxX8\(\)\]][=\-"^:]?[)>$&|\w\(\)*##?]?[)>$&|\w\(\)*##?]/g;
I tried few things that didn't work without messing up the original match.
For the Don't-parse-html-with-regex-police-department: this is running server side and I do not have the luxury for a DOM parser at the moment.
Thank you.
UPDATE: for a RegExp solution to ignore <code> tags see this neat solution thanks to github/frissdiegurke in this commit
/(^|<\/code>)([^<]*|<(?!code>))*(<code>|$)/g
Without DOM parsing you are going to have edge cases which will fail. But, this should work for you.
Given this HTML:
Hello :) <pre>Wassup :)</pre> Maybe :) <code>:) Foo</code> :) Bar
Use this code:
var blocks = [];
html = html.replace(/(?:<pre>.*?<\/pre>|<code>.*?<\/code>)/g, function (match) {
blocks.push( match );
return '__BLOCK__';
});
html = html.replace(/:\)/g, 'SMILE');
html = html.replace(/__BLOCK__/g, function () {
return blocks.shift();
});
Which produces:
Hello SMILE <pre>Wassup :)</pre> Maybe SMILE <code>:) Foo</code> SMILE Bar
Just adjust the /:\)/g replace to work however you need it.
Guess you're using nodejs or a recent javascript engine (for "map" & "split" implementations), so you can do this:
function replaceSpecial(str, pattern, replacement) {
var REG = /(<code>.*?<\/code>)|(<pre>.*?<\/pre>)/i;
return str.split(REG).map(function(s) {
if ('' + s !== s)
return '';
if (s.match(REG))
return s;
return s.replace(pattern, replacement);
}).join('');
}
Example:
replaceSpecial("hey :) <code>:)</code> :'( <pre> :'( :)</pre>", /(:\))|(:'\()/, function(s) {
switch(s) {
case ":)":
return '<img src="smile.gif" />';
case ":'(":
return '<img src="cry.gif" />';
}
})
Will return:
"hey <img src="smile.gif" /> <code>:)</code> <img src="cry.gif" /> <pre> :'( :)</pre>"
Or easier if you just want to replace an emoticon:
replaceSpecial("hey :) <code>:)</code>", ":)", '<img src="smile.gif" />')
=>
"hey <img src="smile.gif" /> <code>:)</code>"
var co = -1, ce = 0, start=0, result;
while ( ce != -1 ) {
co = testString.indexOf('<code', ce);
if (co > -1) {
result += parse(testString.substring(start,co), pattern1);
start = co+1;
ce = testString.indexOf('</code>', co + 5);
if (ce >-1 ){
start = ce + 7;
ce = start;
result += testString.substring(co,ce);
}
}
}
result += parse(testString.substring(start), pattern1);
console.log(result);

checking text area for ling and changing them into hyperlink

So I have this function here:
function ShowMessage()
{
var themessege = document.getElementById("Form").textarea1.value;
var dat = new Date();
var fileName = document.getElementById("theFile").value;
var image = '<img src="' + fileName + '"/>' + '<br>';
document.getElementById("Form").textarea1.value = "";
document.getElementById("Form").countdown.value = "160";
document.getElementById("theFile").value = "";
if (themessege==null || themessege=="")
{
alert("There is no text to submit, please fill out the text box");
return false;
}
document.getElementById("blog").innerHTML = document.getElementById("blog").innerHTML + image + "Guest post: " + themessege + "<br />" + dat +"<br />";
}
I can get the text from the text area, as well as the image the user uploads. I'm wondering how I can divide the strings in the text area into subsrtings to check if they start with "www" or "htt".
This is what I've written so far:
function linkify(inputText) {
var replaceText, replacePattern1, replacePattern2;
//URLs starting with http://, https://
replacePattern1 =https;
replacedText = inputText.replace(replacePattern1, '<a href= ></a>');
//URLs starting with "www." (without // before it, or it'd re-link the ones done above).
replacePattern2 = www.;
replacedText = replacedText.replace(replacePattern2, <a href="http: ></a>');
var x = getelementbyid("blog");
for(var i = 0;i < x.length;i++){
if(blog.charAt(i) == replacePattern1){
return replacedText;
}
}
else if(blog.charAt(i) == replacePattern2){
return replacedText;
}
}
I know that the charAt(i) only checks for 1 letter....
Most of the answers that I found were on PHP, I'm trying to find a solution using JavaScript.
linkify function is not correctly written. try this one.
function linkify(inputText) {
var regUrl = /(http:[\d]{0,4}\/\/)?[a-zA-Z0-9\-\.]+\.(com|org|net|mil|edu|COM|ORG|NET|MIL|EDU)/;
return inputText.replace(regUrl,'<a href="" />');
}
;
alert(linkify('string containing link www.google.com'));// output: string containing link <a href="" />
Your linkify function is all wrong. All your variables contain references to variables that don't exist! Put quotes around them to make them strings.
What does this replacedText = inputText.replace(replacePattern1, '<a href= ></a>'); do?
Say inputText is 'https://example.com' and assuming you corrected your variables, so that replacePattern1 === 'https'
You find the https and replace it with . What does the final product look like?
replacedText === '<a href= ></a>://example.com';
Same thing happens with the second replace pattern.
Further, there is nothing like getelementbyid. It's document.getElementById. JavaScript is case-sensitive. It returns a single element with an id, so you can't loop through it.
Please, learn JavaScript before you try writing JavaScript code. Here's a good resource to start. Also, read JavaScript: The Good Parts, by Douglas Crockford.
Answering your question, here is the code you should use:
string.replace(/(https?:\/\/[^\s]+)/g, "<a href='$1'>$1</a>")
The https? means either http or https. The [^\s]+ means anything but a whitespace character. The $1 means the entire matched URL.
This is a good reference for Regular Expressions in JavaScript
This will allow for https and http URLs containing letters and numbers and convert the URLs into links.
Demo

Regex replace url with links

I need a little help with some regex I have. Basically I have a shout box that only shows text. I would like to replace urls with links and image urls with the image. I've got the basics working, it just when I try to name a link that I have problems, well if there is more than one link... check out the demo.
Named link format {name}:url should become name. The problem I am having is with shout #5 where the regex doesn't split the two urls properly.
HTML
<ul>
<li>Shout #1 and a link to google: http://www.google.com</li>
<li>Shout #2 with an image: http://i201.photobucket.com/albums/aa236/Mottie1/SMRT.jpg</li>
<li>Shout #3 with two links: http://www.google.com and http://www.yahoo.com</li>
<li>Shout #4 with named link: {google}:http://www.google.com</li>
<li>Shout #5 with two named links: {google}:http://www.google.com and {yahoo}:http://www.yahoo.com and {google}:http://www.google.com</li>
</ul>
Script
var rex1 = /(\{(.+)\}:)?(http\:\/\/[\w\-\.]+\.[a-zA-Z]{2,3}(?:\/\S*)?(?:[\w])+)/g,
rex2 = /(http\:\/\/[\w\-\.]+\.[a-zA-Z]{2,3}(?:\/\S*)?(?:[\w])+\.(?:jpg|png|gif|jpeg|bmp))/g;
$('ul li').each(function(i){
var shout = $(this);
shout.html(function(i,h){
var p = h.split(rex1),
img = h.match(rex2),
typ = (p[2] !== '') ? '$2' : 'link';
if (img !== null) {
shout.addClass('shoutWithImage')
typ = '<img src="' + img + '" alt="" />';
}
return h.replace(rex1, typ);
});
});
Update: I figured it out thanks to Brad helping me with the regex. In case anyone needs it, here is the updated demo and code (Now works in IE!!):
var rex1 = /(\{(.+?)\}:)?(http:\/\/[\w\-\.]+\.[a-zA-Z]{2,3}(?:\/\S*)?(?:[\w])+)/g,
rex2 = /(http:\/\/[\w\-\.]+\.[a-zA-Z]{2,3}(?:\/\S*)?(?:[\w])+\.(?:jpg|png|gif|jpeg|bmp))/g;
$('ul li').each(function(i) {
var shout = $(this);
shout.html(function(i, h) {
var txt, url = h.split(' '),
img = h.match(rex2);
if (img !== null) {
shout.addClass('shoutWithImage');
$.each(img, function(i, image) {
h = h.replace(image, '<img src="' + image + '" alt="" />');
});
} else {
$.each(url, function(i, u) {
if (rex1.test(u)) {
txt = u.split(':')[0] || ' ';
if (txt.indexOf('{') >= 0) {
u = u.replace(txt + ':', '');
txt = txt.replace(/[\{\}]/g, '');
} else {
txt = '';
}
url[i] = '' + ((txt == '') ? 'link' : txt) + '';
}
});
h = url.join(' ');
}
return h;
});
});
(\{(.+?)\}:)
you need the ? to make the regex become "ungreedy" and not just find the next brace.
EDIT
However, if you remove the {yahoo}: the second link becomes null too (seems to populate the anchor tag, just no attribute within). This almost seems to be a victim of using a split instead of a replace. I would almost recommend doing a once-over looking for links first, then go back around looking for images (I don't see any harm in off-linking directly to the image, unless that's not a desired result?)

Categories