0

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.

<a href="http://google.co.uk">Google</a>
<a href="http://google.com">Google 2</a>
<a href="http://google.co.uk">Google 3</a>

My code returns

<a href="http://google.co.uk">{{tracking_link0}}</a>
<a href="http://google.com">{{tracking_link1}}</a>
<a href="http://google.co.uk">Google 3</a>

It should return instead

<a href="http://google.co.uk">{{tracking_link0}}</a>
<a href="http://google.com">{{tracking_link1}}</a>
<a href="http://google.co.uk">{{tracking_link0}}</a>

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

wiredmark
  • 1,098
  • 6
  • 26
  • 44

3 Answers3

3

/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, "\\$&");
};
Community
  • 1
  • 1
Quinn
  • 136
  • 5
  • For some reasons it isn't working, but I get no error in the console. My snippet of code is in a simple function called `detect_links()` that is run when a button is clicked. Could this be the reason? – wiredmark Dec 28 '16 at 15:48
  • Also my urls might contain parameters, like `http://tracking.testapp.com/affil?offer=105&id=1152` – wiredmark Dec 28 '16 at 15:51
  • @wiredmark Could you be more specific on how it isn't working? What is the result? Could you put more relevant code in your post, perhaps a working example? – Quinn Dec 28 '16 at 15:51
  • yes, the textarea remains unchanged and I get no error in the console. I will add something more to my code – wiredmark Dec 28 '16 at 15:52
  • 1
    @wiredmark The problem was that `RegExp()` still parsed some parts of the variable `value` as though they were special characters. I updated my answer. It should be working now. – Quinn Dec 28 '16 at 16:00
  • thank you very much. It works indeed. You have been very kind even though it was my fault not thinking about the URLs might contain special values. I can keep working on my script now. Have a nice day ahead! – wiredmark Dec 28 '16 at 16:03
  • can you tell me how come if I have two links like `http://tracking.test.com/aff_c?offer_id=1565&aff_id=1192&file_id=4851` and `http://tracking.test.com/aff_c?offer_id=1565&aff_id=1192&file_id=4851&url_id=1069`, very similar with the only exception of the last extra parameter, the first one gets replaced with `{{tracking_link0}}` and the second one with `{{tracking_link0}}&url_id=1069`? – wiredmark Dec 28 '16 at 17:35
  • from the tests I run it looks like every single extra character isn't checked. E.g. if I have `http://tracking.test.com/aff_c?offer_id=1565&aff_id=1192&fil‌​e_id=4851A` it will return me `{{tracking_link0}}A` which is really weird – wiredmark Dec 28 '16 at 17:44
  • 1
    @wiredmark To fix that, make `value` more specific. Add `href="` to the beginning of it and `"` to the end. Then do the same for what you are replacing it with (from `'{{tracking_link' + key + '}}'` to `'href="{{tracking_link' + key + '}}"'`). As a whole, the line should become `var newHTML = $("textarea[name=html]").val().replace(new RegExp(escapeRegExp('href="' + value + '"'), "g"), 'href="{{tracking_link' + key + '}}"');`. – Quinn Dec 28 '16 at 21:43
1

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"><a href="http://google.co.uk">Google</a>
<a href="http://google.com">Google 2</a>
<a href="http://google.co.uk">Google 3</a>
</textarea>
Rory McCrossan
  • 331,213
  • 40
  • 305
  • 339
  • For some reasons it isn't working, but I get no error in the console. My snippet of code is in a simple function called `detect_links()` that is run when a button is clicked. Could this be the reason? In this case I tried removing the `return` but I get a blank `textarea` – wiredmark Dec 28 '16 at 15:48
1

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"><a href="http://google.co.uk">Google</a>
<a href="http://google.com">Google 2</a>
<a href="http://google.co.uk">Google 3</a>
</textarea>

This replace the text inside the links

LellisMoon
  • 4,810
  • 2
  • 12
  • 24