regex replace jumbles string - javascript

This is my console.log:
str : +0-D : replace : Da href="Javascript:PostRating('','|P|622','+0')">+0</a>-D
I have the following function:
function replaceAll_withMatching(str, find, rep, prodId) {
//console.log(str + " : " + find + " : " + rep + " : " + prodId);
var returnString = "";
if (find.toLowerCase() == str.toLowerCase()) {
returnString = rep;
} else {
escfind = "\\" + find ;
var regexp = new RegExp(escfind, "i");
var match = regexp.test(str);
if (match) {
var regAHREF = new RegExp("\\<a", "i");
var AHREFMatch = regAHREF.test(str);
if (AHREFMatch == false) {
str = str.replace(regexp, rep);
str = replaceProductAll(str, PRODUCT_PLACEHOLD, prodId);
} else {
var aTagText = $($.parseHTML(str)).filter('a').text();
if ((find !== aTagText) && (aTagText.indexOf(find) < 0)) {
console.log(regexp);
console.log("str : " + str + " : replace : " + str.replace(regexp, rep));
str = str.replace(regexp, rep);
}
}
}
//console.log(str);
returnString = str;
}
//returnString = replaceProductAll(returnString, PRODUCT_PLACEHOLD, prodId);
return returnString;
}
This function looks for a "<a>" tag, if it doesn't find one then it does the replace. If it does find one it has some conditions that if everything checks out it does another replace.
The string that I'm passing in has been already "parsed" on the +0:
+0-D
In the second pass I'm expecting it to find the "D" in the above string, and then do the following replacement:
D
But as you can see, after the 2nd replace it is jumbling the string and producing malformed HTML
Da href="Javascript:PostRating('','|P|622','+0')">+0</a>-D
More Context:
I have a string that needs to have a replace done on it. This is existing code so I'm not in a position to rework the function.
The original string is: +0-D
This string gets passed into the function below multiple times looking for matches and then if it finds a match it will replace it with the value (also passed in as a parameter).
When the +0-D gets passed in the first time the +0 is matched and a replace is done: +0
Then the next time the string is passed in: +0-D. The function finds the D as a match and it looks like it attempts to do a replace. But it is on this pass that the string gets jumbled.
Ultimately what I'm expecting is this:
+0-D
This is what I'm currently getting after the 2nd attempt:
Da href="Javascript:PostRating('','|P|622','+0')">+0</a>-D
Further Context:
The +0-D is one of many strings this function handles. Some are very simple (i.e. Just +0), others are much more complex.
Question:
Based on the above, what do I need to do to get the regex to not jumble the string?

The problem was in the escfind:
escfind = "\\" + find;
var regexp = new RegExp(escfind,"i");
var match = regexp.test(str);
The first thing I did was in the 2nd replace clause I created a new RegExp to not use the "\\" + find;
if((find !== aTagText) && (aTagText.indexOf(find) < 0)){
try{
var regexp2 = new RegExp(find,"i");
var match2 = regexp2.test(str);
console.log(str.replace(regexp2,rep));
}catch(err){
console.log(err);
}
}
Then my string began to return as expected, however, when I opened it up to all the variations I was getting the Unexpected quantifier error.
Then I found this question - which lead me to escape out my find:
Once I replaced my code with this:
escfind = find.replace(/([*+.?|\\\[\]{}()])/g, '\\$1');
Then I got the output as expected:
<a href='+0'>+0</a>-<a href='D'>D</a>

Related

Update uri hash javascript

I find it hard to believe this hasn't been asked but I can find no references anywhere. I need to add a URI hash fragment and update the value if it already is in the hash. I can currently get it to add the hash but my regex doesn't appear to catch if it exists so it adds another instead of updating.
setQueryString : function() {
var value = currentPage;
var uri = window.location.hash;
var key = "page";
var re = new RegExp("([#&])" + key + "=.*#(&|$)", "i");
var separator = uri.indexOf('#') !== -1 ? "&" : "#";
if (uri.match(re)) {
return uri.replace(re, '$1' + key + "=" + value + '$2');
}
else {
return uri + separator + key + "=" + value;
}
},
Also if this can be made any cleaner while preserving other url values/hashes that would be great.
example input as requested
Starting uri value:
www.example.com#page=1 (or no #page at all)
then on click of "next page" setQueryString gets called so the values would equal:
var value = 2;
var uri = '#page1'
var key = 'page'
So the hopeful output would be '#page2'.
As to your regex question, testing if the pattern #page=(number) or &page=(number) is present combined with capturing the number, can be done with the regex /[#&]page\=(\d*)/ and the .match(regex) method. Note that = needs escaping in regexes.
If the pattern exists in the string, result will contain an array with the integer (as a string) at result[1]. If the pattern does not exist, result will be null.
//match #page=(integer) or &page=(integer)
var test = "#foo=bar&page=1";
var regex = /[#&]page\=(\d*)/;
var result = test.match(regex);
console.log(result);
If you want to dynamically set the key= to something other than "page", you could build the regex dynamically, like the following (note that backslashes needs escaping in strings, making the code a bit more convoluted):
//dynamically created regex
var test = "#foo=bar&page=1";
var key = "page"
var regex = new RegExp("[#&]" + key + "\\=(\\d*)");
var result = test.match(regex);
console.log(result);

String replace module definition

Below I'm trying to replace the moduleName string with another string replacementModule.
var replacementModule = 'lodash.string' // cheeky
var moduleName = 'underscore.string'
var pattern = new RegExp('^' + moduleName + '(.+)?')
var match = definition.match(pattern)
var outcome = replacementModule + match[1]
However right now a totally different module is matched as well.
underscore.string.f/utils // desired no change
underscore.string.f // desired no change
underscore.string // => lodash.string
underscore.string/utils // => lodash.string/utils
How can I match to the /, and how the outcome that I expect?
You need to do at least 3 things:
Escape the string variable passed to the RegExp
Check if match is null before using it
The regex should contain ($|/.*) as capturing group 1 to match either an end of string or / followed by 0 or more characters.
RegExp.escape = function(s) {
return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};
function runRepl(definition, replacementModule, moduleName) {
var pattern = RegExp('^' + RegExp.escape(moduleName) + '($|/.*)');
// ^------------^ ^------^
var match = definition.match(pattern);
if (match !== null) { // Check if we have a match
var outcome = replacementModule + match[1];
document.write(outcome + "<br/>");
}
else {
document.write("N/A<br/>");
}
}
runRepl("underscore.string.f/utils", "lodash.string", "underscore.string");
runRepl("underscore.string.f", "lodash.string", "underscore.string");
runRepl("underscore.string", "lodash.string", "underscore.string");
runRepl("underscore.string/utils", "lodash.string", "underscore.string");
Escaping is necessary to match a literal . inside moduleName and ($|/)(.+)? presumes there can be something after an end of string. Also, (.+)? (1 or more characters) is actually the same as .* which is shorter and easier to read.

Why can't I do a .split() on a string with a space in it with Google Apps Script?

I'm having a hard time getting the .split() function to work when the string by which it's being split has spaces or any characters other than simple letters or numbers in it. I've tried escaping them with backslash notation, but it's not working. The code below doesn't supply a second item in the resulting array.
function isGoodSerp(kw, optResults, optTld, optStart) {
errorOccurred = false;
kw = kw || "office 365";
optResults = optResults || 10;
optStart = optStart || 0;
optTld = optTld || '.com';
try {
var url = 'http://www.google' + optTld + '/search?q=' + kw + '&start=' + optStart + '&num=' + optResults;
var fullHtml = UrlFetchApp.fetch(url).getContentText();
var noHeaderHtml = fullHtml.split("Search Results");
Logger.log("noHeaderHtml" + noHeaderHtml[1]);
} catch(e) {
errorOccurred = true;
return e;
}
}
I think, the text you want to split with does not exists in the resulting page (as Babajide Fowotade already stated). Thus the result is a single element with the complete fullHtml-content.
Example:
console.log(("test").split('XXX'));
results in ["test"].
I don't know what you are trying to reach. There is no text "Search results" in the google search results page - at least not if I use it...
Split is working by searching for the text you provide and return the text "around".
Example:
console.log(("this is a test").split(' '));
results in ["this", "is", "a", "test"].

Convert special character to string in javascript

Hi I have a vbscript function which replace the special character to string. I am replacing that function to javascript, but it is showing error. Below is the funciton
<script language="vbscript">
Function ReplaceSpecialChars(strValue)
if strValue <> "" then
strValue=Replace(strValue,"\","\\")
strValue=Replace(strValue,"[","\[")
strValue=Replace(strValue,"]","\]")
strValue=Replace(strValue,"*","\*")
strValue=Replace(strValue,"^","\^")
strValue=Replace(strValue,"$","\$")
strValue=Replace(strValue,".","\.")
strValue=Replace(strValue,"|","\|")
strValue=Replace(strValue,"?","\?")
strValue=Replace(strValue,"+","\+")
strValue=Replace(strValue,"(","\(")
strValue=Replace(strValue,")","\)")
strValue=Replace(strValue,"{","\{")
strValue=Replace(strValue,"}","\}")
end if
ReplaceSpecialChars=strValue
End Function
I converted this function to javascript function as below:
var replaceSpecialChars = function (strValue) {
if (strValue !== "") {
strValue = strValue.replace("\'", "\\''");
//strValue = strValue.replace(/\\/g, "\\\\");
strValue = strValue.replace("[", "\[");
strValue = strValue.replace("]", "\]");
strValue = strValue.replace("*", "\*");
strValue = strValue.replace("^", "\^");
strValue = strValue.replace("$", "\$");
strValue = strValue.replace(".", "\.");
strValue = strValue.replace("|", "\|");
strValue = strValue.replace("?", "\?");
strValue = strValue.replace("+", "\+");
strValue = strValue.replace("(", "\(");
strValue = strValue.replace(")", "\)");
strValue = strValue.replace("{", "\{");
strValue = strValue.replace("}", "\}");
}
return strValue;
};
Which is being used by the following line:
var a = function(value) {
var varC = "(?:^|\\s)(" + replaceSpecialChars(value) + ")(?=\\s|$)"
varRegExp = new RegExp(varC, "ig")
if (expression1.search(varRegExp) != -1) {
alert("Duplicate value not allowed in Record " + (i + 1));
return false;
};
But it is showing error.
EDIT
That code you posted for the replaceSpecialChars function works (when you uncomment the line that replaces the '\' character with '\') for the first of each character.
I expect that the error is because your replaces weren't replacing ALL instances, so your regex had a bunch of special characters left over.
You'll want
String.prototype.replace()
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/replace
In order to make it replace all instances you will need a regular expression with the additional character 'g' (these initialisations are equivalent, but the second one is preferred)
var regex = new RegExp('pattern', 'g');
var betterRegex = /pattern/g;
The 'g' tells it to find all instances, otherwise it would stop at the first.
However, be careful with the second initialisation...
var regex = /\/g;
Is going to throw an error, because it won't be able to find the closing '/' symbol, since you told it to escape it. What you want is:
var regex = /\\/g;
Which tells it to look for the character '\'.
Something similar happens for all of the other characters as well, so make sure you escape them all in your regex's.
For a string, only the '\' has to be escaped like that; the other characters don't need.
So, your function is going to look something like this...
function replaceSpecialChars(str) {
var result;
if (str !== "") {
result = str.replace(/\\/g, '\\\\');
result = str.replace(/\[/g, '\[');
result = str.replace(/\]/g, '\]');
result = str.replace(/\*/g, '\*');
...
}
return result;
}
For the full list of characters that have special meaning in RegExp and what they do see...
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
(You actually have to work out the special characters from the descriptions, but you've already listed pretty much ALL of the special characters in a regex)

Javascript get integer value of url parameter to replace it in function

I have some difficulties with javascript. I'm currently working out a pagination skipper.
function skip(s)
{
var url = window.location.toString();
if(location.href.match(/(\?|&)currentpage=x($|&|=)/))
{
url=url.replace('currentpage=x','currentpage='+s);
window.location=url;
}
else
{
var newUrl = url+"&currentpage="+s;
window.location=newUrl;
}
}
I would like x to match any integer, so the entire string will be replaced.
Thanks!
The regex you're looking is this:
/((\?|&)currentpage=)\d+/
It matches and captures ?|&currentpage=, and matches the number that follows, but does not capture them. You can then replace the entire match with a string of your choice:
var newUrl = location.href.replace(/([?&]currentpage=)\d+/, '$1'+s);
Assuming that s here is the value for currentpage you want to replace the x in your example with. I've replaced the (\?|&) with a character class: [?&]. It simply matches a single character that is either a ? or an &. In the replacement string I back-reference the matched group ([?&]currentpage=), using $1, and concatenate s to it. It's as simple as that. To redirect:
location.href = location.href.replace(
/([?&]currentpage=)\d+/,
'$1' + s
);
And you're home free. Try it out in your console, like so:
'http://www.example.com/page?param1=value1&currentpage=123&param2=foobar'.replace(
/([?&]currentpage=)\d+/,
'$1124'//replaced + s with 124
);
//output:
//"http://www.example.com/page?param1=value1&currentpage=124&param2=foobar"
You can use following code,
function addParameter(url, param, value) {
// Using a positive lookahead (?=\=) to find the
// given parameter, preceded by a ? or &, and followed
// by a = with a value after than (using a non-greedy selector)
// and then followed by a & or the end of the string
var val = new RegExp('(\\?|\\&)' + param + '=.*?(?=(&|$))', 'i'),
qstring = /\?.+$/;
// Check if the parameter exists
if (val.test(url)) {
// if it does, replace it, using the captured group
// to determine & or ? at the beginning
return url.replace(val, '$1' + param + '=' + value);
}
else if (qstring.test(url)) {
// otherwise, if there is a query string at all
// add the param to the end of it
return url + '&' + param + '=' + value;
}
else {
// if there's no query string, add one
return url + '?' + param + '=' + value;
}
}
Usage,
function skip(s) {
window.location = addParameter(location.href, "currentpage", s);
}
Demo

Categories