Does anyone see why the first three searches in the jsfiddle here - http://jsfiddle.net/tJ9uQ/ return -1?
Thanks
var gotoTarget = "http://register.php?from=";
var off1 = gotoTarget.search('register.php?from=');
console.log ("off1="+off1);
off2 = gotoTarget.search('register.php\?from=');
console.log ("off2="+off2);
off3 = gotoTarget.search('register.phpfrom=');
console.log ("off3="+off3);
off4 = gotoTarget.search('register.php');
console.log ("off4="+off4);
The parameter passed to .search() is a regular expression. If a regular expression is not passed, what is passed is implicitly converted to a regular expression.
Per the MDN Docs:
str.search(regexp)
Parameters
A regular expression object. If a non-RegExp object obj is passed, it is implicitly converted to a RegExp by using new RegExp(obj).
You need to escape the question mark, as the question mark is a valid regex character.
var off1 = gotoTarget.search('register\\.php\\?from=');
console.log(off1); // returns 7
In your examples above, the first one is not escaped at all, the second is incorrectly escaped and third is missing the ? so no match will be found.
Fiddle
Related
I have a string like aman/gupta and I want to replace it to aman$$gupta and for that I am using JavaScript replace method as follows:
let a = "aman/gupta"
a = a.replace("/", "$")
console.log(a) // 'aman$gupta'
a = "aman/gupta"
a = a.replace("/", "$$")
console.log(a) // 'aman$gupta'
a = "aman/gupta"
a = a.replace("/", "$$$")
console.log(a) // 'aman$$gupta'
Why are the 1st and 2nd case identical and I get the expected result when I use $$$ instead of $$?
It’s because $$ inserts a literal "$".
So, you need to use:
a = "aman/gupta";
a = a.replace("/", "$$$$"); // "aman$$gupta"
See the following special patterns:
Pattern
Inserts
$$
Inserts a "$".
$&
Inserts the matched substring.
$`
Inserts the portion of the string that precedes the matched substring.
$'
Inserts the portion of the string that follows the matched substring.
$n
Where n is a non-negative integer less than 100, inserts the _n_th parenthesized submatch string, provided the first argument was a RegExp object.
$<Name>
Where Name is a capturing group name. If the group is not in the match, or not in the regular expression, or if a string was passed as the first argument to replace instead of a regular expression, this resolves to a literal (e.g., "$<Name>").
Also you can use split and join for better performance and $ isn't special for those functions.
var a = "aman/gupta"
a = a.split('/').join('$$')
alert(a); // "aman$$gupta"
To avoid the need to escape special characters you can use anonymous function as a replacer
a = "aman/gupta";
a = a.replace("/", function() {return "$$"});
console.log(a); // "aman$$gupta"
String.prototype.replace() documentation
Specifying a function as a parameter
You can specify a function as the second parameter. In this case, the function will be invoked after the match has been performed. The function's result (return value) will be used as the replacement string. (Note: the above-mentioned special replacement patterns do not apply in this case.) Note that the function will be invoked multiple times for each full match to be replaced if the regular expression in the first parameter is global.
The replace method provides replacement patterns that start with a dollar sign. One of them is $$ which inserts a single $. A single dollar sign in the replacement string will result in a literal one.
So if you want clean literal dollar signs, use $$ replacement patterns accordingly:
console.log('aman/gupta'.replace('/','$$')); // aman$gupta
console.log('aman/gupta'.replace('/','$$$$')); // aman$$gupta
console.log('aman/gupta'.replace('/','$$$$$$')); // aman$$$gupta
In regular expression replace with groups, if replacement is a variable, it needs to dollar sign escaped. Otherwise there will be bugs.
function escapeDollarSign(str) {
return str.replace(/\$/g, "$$$$")
}
Use below code its working for me.
var dollar = "$$$$";
console.log('abhishe/kadam'.replace('/', dollar.replace(new RegExp('\\$', 'g'), '$$$')));
This question already has answers here:
Is there a RegExp.escape function in JavaScript?
(18 answers)
Closed 3 years ago.
I have this Example 1:
myString = 'cdn.google.com/something.png';
console.log(myString.match(myString));
Everything works just fine, but when it comes to Example 2:
myString = 'cdn.google.com/something.png?231564';
console.log(myString.match(myString));
It returns the value of 'null'. I don't know what happened anymore.. I searched for the keywords 'a string does not Match itself' and found nothing. Can somebody help me? Thank you.
The String#match method would treat the argument as a regex(by parsing if not), where . and ? has special meaning.
. matches any character (except for line terminators)
? Quantifier — Matches between zero and one times, as many times as possible, giving back as needed
So . wouldn't cause any problem since . can be used to match any character except line but ? would since it's using to match zero or one-time occurrence of any character.
For eg: .png?23 => matches .png23 or .pn23
From MDN docs :
If a non-RegExp object obj is passed, it is implicitly converted to a RegExp by using new RegExp(obj).
It's better to use String#indexOf instead which returns the index in the string if found or returns -1 if not found.
console.log(myString.indexOf(myString) > -1);
match in Javascript compares a String against a RegEx. Luckily in your first example it works.
I guess you are looking for a method like localCompare.
Hope this helps!
match() search the string using a regular expression pattern.
So
var s = "My String";
s.match(/Regex Here/);
will try to match s for given regular expression .
In your example:-
myString = 'cdn.google.com/something.png'; // It will be treated as regex
console.log(myString.match(myString));
myString = 'cdn.google.com/something.png?231564'; // It will be treated as regex , result differ because of ?
console.log(myString.match(myString));
You can escape the argument to match, however if you do that you could just use == to compare the strings. This post contains a regex string escape function:
How to escape regular expression in javascript?
RegExp.quote = function(str) {
return (str+'').replace(/[.?*+^$[\]\\(){}|-]/g, "\\$&");
};
It can be used like this:
myString = 'cdn.google.com/something.png?231564';
console.log(myString.match(RegExp.quote
(myString)));
If you want to match any number after the question mark, you could do it like this:
myString = 'cdn.google.com/something.png?';
console.log((myString+"18193819").match(RegExp.quote
(myString) + '\\d+'));
If you try searching strings such as "[]" or "()" using the search() function it doesn't work.
function myFunction() {
var str = "Visit []W3Schools!";
var n = str.search("[]");
document.getElementById("demo").innerHTML = n;
}
You can try on W3Schools at -
https://www.w3schools.com/jsref/tryit.asp?filename=tryjsref_search
Searching [] returns -1, while searching () returns 0. Always.
Why is that?
String.search uses a RegExp, and converts its argument to one if it isn't already. [] and () are special characters to RegExp.
You can directly create a regexp and escape the characters like so:
var n = str.search(/\[\]/);
But if you're searching for a literal string, then you should be using String.indexOf instead.
var n = str.indexOf("[]");
The JavaScript search function takes a regular expression as its argument:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/search
In regular expressions, "[" and "(" are special characters.
Try replacing your function with this:
function myFunction() {
var str = "Visit []W3Schools!";
var n = str.search("\\[]");
document.getElementById("demo").innerHTML = n;
}
or better:
var n = str.search(/\[]/);
The '[' special character is escaped. Once that is escaped, the ']' does not need to be escaped because it is only treated special after an unescaped '['.
For more information about regular expressions in JavaScript, look here:
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp
It's because search is expecting a regular expression. If a string is passed, then search will explicitly transform it into a regexp using new RegExp.
Calling it like str.search("[]") is like calling it str.search(/[]/) (nothing in the string matches an empty set so -1 is returned).
And calling it like str.search("()") is like calling it str.search(/()/) (the first empty string "" is found at the index 0).
I recommend looking for the docs on MDN not W3Schools.
Because the search string is a regular-expression and "[]" and "()" are both magic. You need to double-escape them:
str.search("\\[\\]")
Or even better, as ephemient points out:
str.indexOf("[]")
I made code with:
element(by.className('charge')).getText()
.then(function(text){
var blabla = "Is this my string?";
expect(text.match(blabla)).toBe(true);
console.log(text);
});
And even is output of my console equal to my blabla variable,
I'm getting result:
Expected [ 'Is this my string' ] to be true.
without any "?" sign.
How is it possible?
The argument for match is:
A regular expression object. If a non-RegExp object obj is passed, it is implicitly converted to a RegExp by using new RegExp(obj).
So don't pass it a string. Explicitly pass it a regular expression object (since that involves much less pain that converting strings in to regex and having to deal with two levels of syntax to escape through).
Regular expressions treat ? as a special character (in the context of your code it means "The g should appear 0 or 1 time". You need to escape question marks if you want to match them.
var blabla = /Is this my string\?/;
That said, if you want to match the whole string, it would be easier to just make that the test:
var blabla = "Is this my string?";
expect(text).toBe(blabla);
The argument to match is meant to be a regular expression where ? has a special meaning. You probably meant toEqual() instead:
expect(element(by.className('charge')).getText()).toEqual("Is this my string?");
If you want a regular expression match, make a regular expression object and use toMatch():
var blabla = /Is this my string\?/;
expect(element(by.className('charge')).getText()).toMatch(blabla);
Note that in protractor expect() is "patched" to resolve promises implicitly and you don't need to use then().
You probably misundertood what match method does in JS strings:
https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/match
It will basically use the regex to return the groups that match, so, in this case
< ("Is this my string").match("Is this my string?");
> ["Is this my string"]
The answer is correct. What you want to do is simply compare the strings, just do:
< "Is this my string" === "Is this my string?";
> false
Note it has nothing to do with the test engine you are using (that I do not know), but there propably is a better way to do it than
expect(text === blabla).toBe(true);
Something
expect(text, blabla).toBeEqual();
So the error message is pretty ;)
The string argument provided to match() is a regular expression and the ? in this context means "match the previous zero or one times". Which it does in your example :-)
You can explicitly escape the question make by writing \?, in which case the behavior will be as you expect.
Cheers,
var string = input.replace(/\[noparse\]([^\]]+)?\[\/noparse\]/ig, '<noparse>'+removeBrackets('$1')+'</noparse>');
This expression should be taking a string and encoding the parts wrapped in [noparse] tags so they don't render in a textarea.
I tested this as:
var string = input.replace(/\[noparse\]([^\]]+)?\[\/noparse\]/ig, '<noparse>test</noparse>');
and:
var string = input.replace(/\[noparse\]([^\]]+)?\[\/noparse\]/ig, '<noparse>'+String('$1')+'</noparse>');
and they work (without the desired effect).
function removeBrackets(input){
return input
.replace(/\[/g, '[')
.replace(/\]/g, '\');
}
What am I doing wrong in trying to pass the back reference into the removeBrackets function?
replace takes a function as callback and passes the capturing groups in the arguments:
var regex = /\[noparse\]([^\]]+)?\[\/noparse\]/ig;
string = string.replace(regex, function(_, match) {
return '<tag>'+ removeBrackets(match) +'</tag>';
});
The first param _ is the full string, unnecessary in most cases.
Your regular expression won't work, because of an error in the negative character set you're using. This fixes it:
input.replace(/\[noparse\]([^\[]+)?\[\/noparse\]/ig, '<noparse>test</noparse>');
^
Then, to perform the actual replacement, you need to pass a function as the second argument to .replace() instead of a simple string.