Probably I am not able to achieve this because I don't know much about regEx.
I have an array of unique links uniqueLinks.
Whenever those links appear in the HTML code I have my textarea, I want them to be replaced with {{tracking_link_N}} where N stands for the key. Right now I have the following function called when a button is pressed
function detect_links() {
var links = [];
var uniqueLinks = [];
var html = $("textarea[name=html]").val();
// Getting all the links in the textarea to replace them
$(html).find('a').each(function() {
links.push($(this).attr('href'));
})
// Creating an array of unique links uniqueLinks
$.each(links, function(i, el) {
if ($.inArray(el, uniqueLinks) === -1) uniqueLinks.push(el);
});
$.each(uniqueLinks, function(key, value) {
var newHTML = $("textarea[name=html]").val().replace(value, '{{tracking_link' + key + '}}');
$("textarea[name=html]").val(newHTML);
});
}
My textarea is:
<textarea name="html" class="form-control" rows="15"></textarea>
With this code so far it only replaces the first occurrence of the URL in the textarea. In some cases however the same URL appears multiple times in the textarea. E.g.
Google
Google 2
Google 3
My code returns
{{tracking_link0}}
{{tracking_link1}}
Google 3
It should return instead
{{tracking_link0}}
{{tracking_link1}}
{{tracking_link0}}
What I tried reading the other discussions is to change the replace() function like this
replace(/value/g, '{{tracking_link' + key + '}}');
But I don't get any appreciable result.
My URLs contain parameters as well, for example:
http://tracking.testapp.com/affil?offer=105&id=1152
Thanks for any help to address this issue.
PS: explaining the downvotes you give to questions makes them more believable
/value/g means to search for the exact string "value" globally. What you want is for it to search for the value of your value variable globally. For this, you must use RegExp() so that JavaScript parses value to mean the value of the variable value instead of the string "value".
var newHTML = $("textarea[name=html]").val().replace(new RegExp(escapeRegExp(value), "g"), '{{tracking_link' + key + '}}');
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
Add this somewhere in your JavaScript code (taken from this post):
escapeRegExp = function(text) {
return text.replace(/[-[\]{}()*+?.,\\^$|#\s]/g, "\\$&");
};
Your issue is because the replace() method only works on the first found instance when you provide it a string value. Instead, if you give it a Regular Expression with the Global flag set (g) then it will find and replace all instances of the provided value.
Also note that you can make the code more succinct by passing a function to val(). Try this:
var uniqueLinks = ['http://google.co.uk', 'http://google.com'];
$.each(uniqueLinks, function(key, value) {
var re = new RegExp(value, 'gi');
$("textarea[name=html]").val(function(i, v) {
return v.replace(re, '{{tracking_link' + key + '}}');
});
});
textarea {
width: 100%;
height: 80px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea name="html">Google
Google 2
Google 3
</textarea>
var uniqueLinks = ['http://google.co.uk', 'http://google.com'],
textArea=$("textarea[name=html]"),
text=textArea.text();
$.each(uniqueLinks, function(key, value) {
var re = new RegExp('"'+value+'">([^<]*)</',"g");
text=text.replace(re,'"'+value+'">{{tracking_link'+key+'}}<');
});
console.log(text);
textArea.text(text);
textarea {
width: 100%;
height: 80px;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<textarea name="html">Google
Google 2
Google 3
</textarea>
This replace the text inside the links
Related
I have an input element and on click of a button I check if its value contains a set of special characters and return a Boolean and it works fine. What I am trying to achieve is once the Boolean is returned if any special character is found in the value I want to display those special characters in a p tag. How can I achieve this? Thanks in advance.
const format = /[ `!##$%^&*_+-=\[\]{};':"\\|<>\/?~]/
const value = $('input').val()
$('button').on('click', function() {
if (format.test(value) == true) {
//something like this
$('p').html(the found special character + 'not allowed')
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input />
<button>click me</button>
<p></p>
If you are looking to find non alphanumeric characters, I would use /[^A-Z0-9,]/ig instead. Also using match allows you to see if results exist and displaying them
const format = /[^A-Z0-9,]/ig
$('button').on('click', function() {
$('p').html("")
const value = $('input').val()
const results = value.match(format)
if (results) {
$('p').html(results.join(',') + ' is not allowed')
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<input />
<button>click me</button>
<p></p>
You can use String.prototype.match function instead of Regexp.prototype.test.
Match function will give you information about result and if you want to see all results you have to use g flag.
It will return array which contains all matches and it will return null if there is not any match.
const format = /[ `!##$%^&*_+-=\[\]{};':"\\|<>\/?~]/g
$('button').on('click', function() {
const value = $('input').val()
const result = value.match(format)
if (result) {
$('p').html(result.join(',') + ' is not allowed')
}
})
More information about match - https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/match
Also you have to put code of getting value of input inside onclick event, because you want to get value of input when you clicked on button not when script executed.
The idea is taken from here
I have the following code:
myApp.filter('parseUrlFilter', function () {
var urlPattern = /^E\d{5}-\d{2}$/;
return function (text, target) {
return text.replace(urlPattern, '<a target="' + target + '" href="http://somepage.com?number=$&">$&</a>') + " | ";
};
});
I'm still trying to understand how this code exactly works but it does not convert the text to URL.
Like E12345-01 does not become somepage.com?number=E12345-01
I think I'm missing something about how the regex works here. Any help will be appreciated.
Edit: added plnkr with somewhat working answer of machinehead115
Without seeing you HTML code I assume that you are actually binding / using the filter there, like so:
<div ng-bind-html="'E12345-01' | parseUrlFilter:'_blank'"></div>
In order to have the filter actually output the link text as code you need to include $sce as a dependency of filter and return the link using $sce.trustAsHtml(link):
angular.module('app', [])
.filter('parseUrlFilter', function($sce) {
var urlPattern = /^E\d{5}-\d{2}$/;
return function(text, target) {
return $sce.trustAsHtml(text.replace(urlPattern, '<a target="' + target + '" href="http://somepage.com?number=$&">$&</a>') + ' | ');
};
});
Here is an example plnk of the code working.
I'm not sure I understand your question, nor your context. My assumption is that you need to extract the number from an incomingString and use that number to generate a new link string. Given those requirements, the below would get you going...
//this var represents the string that would hold the identifier you're interested in
var originString = "blah blah blah E12345-01 more blah blah blah";
function DoIt(incomingString)
{
//create a regex pattern
var urlPattern = new RegExp(/E\d{5}-\d{2}/);
//get the match
var theMatch = urlPattern.exec(incomingString);
//add the match to your new url
var returnString = "www.whateversite.com/number=" + theMatch;
//from here you can do whatever you want with that string
//for now, I'll just return it as is...
return returnString;
}
console.log(DoIt(originString));
here is the working regex for you
([E]\d{5}-\d{2})
check here https://regex101.com/r/O6YFlj/1
The problem is not in your URL matching and replacement code. I extracted the following from your code and used it. Worked perfect:
<script>
var urlPattern = /^E\d{5}-\d{2}$/;
var text = "E12345-01";
document.write(text.replace(urlPattern, '$&') + " | ");
</script>
The issue must be with the value of text. use console.log(text) to see whether you're getting the right value in your variable or not.
currently I am very confused! I have been trying to solve this for a while, and can't seem to crack it. I can't even find an answer on Google.
Currently I am using this Regex I wrote in Javascript:
((?: {4,}|\t+)(?:.*))
Simply, it matches everything that is 4+ spaces out or 1+ tabs out in a textarea. Yea, that sounds familiar you say? It is simply what Stack Overflow does for codeblocks. Now, I have run in to an issue.
Basically I am wanting to replace all of these instances found in the textarea, but first I want to back them up to an array. Now, I am not sure how I grab each match found, and insert it in to the array.
Here is what I have so far:
.replace(/((?: {4,}|\t+)(?:.*))/gi, function (m, g1, g2) {
return //STUCK HERE
}); //Matches Bold
So simply, I just want to grab all matches found in a textarea (Either indented or 4 spaces) and then I would like to add the contents of the match to an array.
How would I go about doing this? Please Help!
You can hit two targets with one bullet:
var items = [];
var re = /((?: {4,}|\t+)(?:.*))/g;
textarea.value = textarea.value.replace(re, function ($0, $1) {
items.push($1);
return 'replacement';
});
If you want to get the code blocks back then:
var codeLines = [];
var reMarkers = /\{\{(.*?)\}\}/g;
var reCodeBlocks = /((?: {4,}|\t+)(?:.*))/g;
var text = textarea.value;
// save and remove code blocks
text = text.replace(reCodeBlocks, function ($0, $1) {
var marker = '{{' + codeLines.length + '}}';
codeLines.push($1);
return marker;
});
// revert to previous state
text = text.replace(reMarkers, function ($0, $1) {
return codeLines[parseInt($1, 10)];
});
If you want to get the array of matches, you can use match() function :
var matchesArray = $('textarea').val().match('/((?: {4,}|\t+)(?:.*))/gi');
and if you want to replace, use simple replace() function :
$('textarea').val().replace('/((?: {4,}|\t+)(?:.*))/gi', 'replaceWith');
Hope this helps.
I'm a javascript novice so this may be a dumb question. I'm trying to generate a script that takes the phrase "(x items)" and changes it to "(x)", where x can represent any number.
Here's what I have now:
<script type="text/javascript">
$(document).ready(function(){
function changeText(){
$(".CartLink:contains('2 items')").html('Cart <span>(2)</span>');
}
changeText();
$(document).ajaxSuccess(function() {
changeText();
});
});
</script>
The above script is able to replace the phrase "(2 items)" with "(2)" but I need to modify the script so that 2 can be any number. Thank you.
This is the HTML that .CartLink element contains:
<li style="display:" class="CartLink">Cart <span>%%GLOBAL_CartItems%%</span></li>
Ideally this should be a server-side task. But if you have a limitation requiring you to do this client-side...
You don't need to replace all of the html. You can simply modify the text of the span:
$('.CartLink span').text(function(_, val) {
return val.replace(' items', '');
});
Your can use split to seperate the count and text.
http://jsfiddle.net/B2meD/
$( document ).ready(function() {
$(".CartLink").html('Cart <span>'+$(".CartLink").text().split(" ")[0]+'</span>');
});
Javascript as a string replace method. So you can simply remove the items part.
var foo = ('2 items');
var newFoo = foo.replace("items", "");
Then newFoo would become ('2')
S('.CartLink').text($('.CartLink').text().split(' ')[0])
Where are you getting the "2" variable from?
var items = 2;
items ++; //items = 3;
$('.Cart').html("Items in cart:" + items.toString() + ". Foo");
See how I added the "+" to add up the strings?
I must add, this is just bad js.
For making your items variable:
var str = "(Items 2)";
var numberStr = "(" + str.split(" ").pop(); //makes "(2)" or use .replace or whatever works.
Keep in mind that making a variable from a string will result in another string. If you want to manipulate your new items var as a number, you have to get an integer like so,
var numberStr = "(3)";
var int = parseFloat(numberStr.replace(/["'()]/g,""));
If you replace your changeText function with this it should work as you want:
function changeText() {
var itemCountSpan = $(".CartLink a span")
if (/(\d+) items/.test(itemCountSpan.text())) {
itemCountSpan.text(RegExp.$1);
}
}
Here's a simple RegEx version.
$(document).ready(function(){
function changeText(){
$(".CartLink").each(function() {
var newhtml = $(this).html().replace(/\((\d+) items\)/, "($1)");
$(this).html(newhtml);
});
}
changeText();
});
It looks at every element with the CartLink class for the string (x items) where x is one or more digits and removes the word "items". $1 is a property that gets set when the (\d+) parenthesised match is made, allowing us to use the number we want in our replacement string.
Sorry to bother you guys again, but here's my dilemma.
There must be a "better" regular expression to identify HTML link from a paragraph text (there can be more than 1 html links in the text). How do I extract all the link and anchor it in javascript?
My attempt (in javascript) is like this:
var urlPattern = "(https?|ftp)://(www\\.)?(((([a-zA-Z0-9.-]+\\.){1,}[a-zA-Z]{2,4}|localhost))|((\\d{1,3}\\.){3}(\\d{1,3})))(:(\\d+))?(/([a-zA-Z0-9-._~!$&'()*+,;=:#/]|%[0-9A-F]{2})*)?(\\?([a-zA-Z0-9-._~!$&'()*+,;=:/?#]|%[0-9A-F]{2})*)?(#([a-zA-Z0-9._-]|%[0-9A-F]{2})*)?";
function extractURLs(s) {
return s.match(new RegExp(urlPattern));
}
//s is of type String
//For testing...
var text = "Check this video out http://ww w.youtube.com/watch?v=y3U3R3b1dOg or http://www.youtube.com/watch?v=sX6Vm0MoPCY";
alert(extractURLs(text));
(spaces on hyperlink has been deliberately added here to allow posting of question in SO).
Result: I only get the 1st hyperlink and not the second one....
Has anybody done something similar or better that I can utilize?
Thanks in advance.
Use the "g" modifier:
function extractURLs(s) {
return s.match(new RegExp(urlPattern, "g"));
}
var urlPattern = "(https?|ftp)://(www\\.)?(((([a-zA-Z0-9.-]+\\.){1,}[a-zA-Z]{2,4}|localhost))|((\\d{1,3}\\.){3}(\\d{1,3})))(:(\\d+))?(/([a-zA-Z0-9-._~!$&'()*+,;=:#/]|%[0-9A-F]{2})*)?(\\?([a-zA-Z0-9-._~!$&'()*+,;=:/?#]|%[0-9A-F]{2})*)?(#([a-zA-Z0-9._-]|%[0-9A-F]{2})*)?";
function extractURLs(s) {
return s.match(new RegExp(urlPattern));
}
var text = "Check this video out http://www.youtube.com/watch?v=y3U3R3b1dOg or http://www.youtube.com/watch?v=sX6Vm0MoPCY";
var results = extractURLs(text);
alert(extractURLs(results[0] + ", " + results[1]));
It is better to write it as,
var urlPattern = /(https?|ftp)://(www\\.)?(((([a-zA-Z0-9.-]+\\.){1,}[a-zA-Z]{2,4}|localhost))|((\\d{1,3}\\.){3}(\\d{1,3})))(:(\\d+))?(/([a-zA-Z0-9-._~!$&'()*+,;=:#/]|%[0-9A-F]{2})*)?(\\?([a-zA-Z0-9-._~!$&'()*+,;=:/?#]|%[0-9A-F]{2})*)?(#([a-zA-Z0-9._-]|%[0-9A-F]{2})*)?/g;
function extractURLs(s) {
return s.match(urlPattern);
}
Here urlPattern is pre-compiled, rather than compiling the RegEx everytime the function is called, hence results in petter performance.