I have to explicitly use trim() for too many variables. Is there anyway I can apply trim to all the string values in code without calling trim explicitly?
Note:
I asked this question out of curiosity to find if there is a way or possibility to do so. Even I dont want to apply trim in all the scenarios. But yes I've to use trim for all the literals and variables I use in an app(I've such a req). So wanted to know if there is a common place where I can change instead of missing few places.
No, there's nothing in JavaScript's strings that will globally enable automatic whitespace trimming for you. You'll have to do it when/where required, which should typically be only a few places (e.g., reading from inputs).
Here's a cool hack. would not recommend:
String.prototype.valueOf = function() {
return this.trim();
};
'query' + (new String(' asdf ')); // "queryasdf"
Related
I'm trying to evaluate an expression which contains power, in string as **. i.e. eval("(22**3)/12*6+3/2").The problem is Internet Explorer 11 does not recognizes this and throws syntax error. Which poly-fill I should use to overcome this? Right now I'm using Modernizr 2.6.2.
example equation would be,
((1*2)*((3*(4*5)*(1+3)**(4*5))/((1+3)**(4*5)-1)-1)/6)/7
((1*2)*((3*(4*5)*(1+3)**(4*5))/((1+3)**(4*5)-1)-1)/6)/7*58+2*5
(4*5+4-5.5*5.21+14*36**2+69/0.258+2)/(12+65)
If it is not possible to do this, what are the possible alternatives?
You cannot polyfill operators - only library members (prototypes, constructors, properties).
As your operation is confined to an eval call, you could attempt to write your own expression parser, but that would be a lot of work.
(As an aside, you shouldn't be using eval anyway, for very good reasons that I won't get into in this posting).
Another (hack-ish) option is to use a regular expression to identify trivial cases of x**y and convert them to Math.pow:
function detectAndFixTrivialPow( expressionString ) {
var pattern = /(\w+)\*\*(\w+)/i;
var fixed = expressionString.replace( pattern, 'Math.pow($1,$2)' );
return fixed;
}
eval( detectAndFixTrivialPow( "foo**bar" ) );
You can use a regular expression to replace the occurrences of ** with Math.pow() invocations:
let expression = "(22**3)/12*6+3/2"
let processed = expression.replace(/(\w+)\*\*(\w+)/g, 'Math.pow($1,$2)');
console.log(processed);
console.log(eval(processed));
Things might get complicated if you start using nested or chained power expressions though.
I think you need to do some preprocessing of the input. Here is how i would approach this:
Find "**" in string.
Check what is on the left and right.
Extract "full expressions" from left and right - if there is just a number - take it as is, and if there is a bracket - find the matching one and take whatever is inside as an expression.
Replace the 2 expressions with Math.pow(left, right)
You can use Babel online to convert javascript for IE 11.
var str='userkwd* type:"Office"';
How do I trim or substr or slice this string to only get 'userkwd'? Also the variable will have quotes as part of it..This one is tricky as if there is no userkwd .i.e. if
var str=' type:"Office"';
it should return null. The * gets appended with userkwd from inputbox..
str.slice(0,str.indexOf('*')); ???
str.split("*")[0]; ????
str.substring(0, str.indexOf('*')); ???
Which one?
str.replace(/\*? type.*/, '');
The answer is trivial. Think if userkwd can contain " ", for example "user kwd". If so, then you cannot use split(" "). If userkwd could contain additional * like user*kwd then you cannot use this character. If the keyword could contain both spaces and * then you should use different method, for example some more complicated regular expression, but try to evalute your suggested methods first.
By the way, in the scenario you have given var str=' type:"Office"'; there is no userkwd at all, there is also no *, so you definitely should not use * if this is valid example. Space seaprator however holds, so I would go for it if possible.
You can also try to find the last occurance of "type:" and get everything what is before it, if empty then change it to null, or something like this. There are really a lot of possibilities, we do not have enough information why you need this functionality and what could be the input...
I was wondering about Javascript performance about using string.replace() or string.substr(). Let me explain what I'm doing.
I've a string like
str = "a.aa.a.aa."
I just have to "pop" last element in str where I always know what type of character it is (e.g, it's a dot here).
It's so simple, I can follow a lot of ways, like
str = str.substr(0, str.length-1) // same as using slice()
or
str = str.replace(/\.$/, '')
Which methods would you use? Why? Is there some lack in performance using this or that method? Length of the string is negligible.
(this is my first post, so if I'm doing something wrong please, notify me!)
For performance tests in JavaScript use jsPerf.com
I created a testcase for your question here, which shows, that substr is a lot faster (at least in firefox).
If you just want the last character in the string, then use the subscript, not some replacement:
str[str.length-1]
Do you have to do this thousands of times in a loop? If not (and "Length of string is negligible"), any way will do.
That said, I'd prefer the first option, since it makes the intention of trimming the last character more clear than the second one (oh, and it's faster, in case you do need to run this a zillion times. Since in the regex case, you need to not only build a new string but also compile a RegExp and run it against the input.)
When you have this kind of doubt, either pick what you like the best (style-speaking, as running this only once doesn't matter much), or use http://jsperf.com.
For this very example, see here why substr is better :-).
The substr way should always be faster than any kind of RegExp. But the performance difference should be minor.
I have IDs that look like: 185-51-671 but they can also have letters at the end, 175-1-7b
All I want to do is remove the hyphens, as a pre-processing step. Show me some cool ways to do this in javascript? I figure there are probably quite a few questions like this one, but I'm interested to see what optimizations people will come up with for "just hyphens"
Thanks!
edit: I am using jQuery, so I guess .replace(a,b) does the trick (replacing a with b)
numberNoHyphens = number.replace("-","");
any other alternatives?
edit #2:
So, just in case anyone is wondering, the correct answer was
numberNoHyphens = number.replace(/-/g,"");
and you need the "g" which is the pattern switch or "global flag" because
numberNoHyphens = number.replace(/-/,"");
will only match and replace the first hyphen
You need to include the global flag:
var str="185-51-671";
var newStr = str.replace(/-/g, "");
This is not faster, but
str.split('-').join('');
should also work.
I set up a jsperf test if anyone wants to add and compare their methods, but it's unlikely anything will be faster than the replace method.
http://jsperf.com/remove-hyphens-from-string
var str='185-51-671';
str=str.replace(/-/g,'');
Gets much easier in String.prototype.replaceAll(). Check out the browser support for the built-in method.
const str = '185-51-671';
console.log(str.replaceAll('-', ''));
Som of these answers, prior to edits, did not remove all of the hyphens. You would need to use .replaceAll("-","")
In tidyverse, there are multiple functions that could suit your needs. Specifically, I would use str_remove, which will replace in a string, the giver character by an empty string (""), effectively removing it (check here the documentation). Example of its usage:
str_remove(x, '-')
I am trying to write some JavaScript RegEx to replace user inputed tags with real html tags, so [b] will become <b> and so forth. the RegEx I am using looks like so
var exptags = /\[(b|u|i|s|center|code){1}]((.){1,}?)\[\/(\1){1}]/ig;
with the following JavaScript
s.replace(exptags,"<$1>$2</$1>");
this works fine for single nested tags, for example:
[b]hello[/b] [u]world[/u]
but if the tags are nested inside each other it will only match the outer tags, for example
[b]foo [u]to the[/u] bar[/b]
this will only match the b tags. how can I fix this? should i just loop until the starting string is the same as the outcome? I have a feeling that the ((.){1,}?) patten is wrong also?
Thanks
The easiest solution would be to to replace all the tags, whether they are closed or not and let .innerHTML work out if they are matched or not it will much more resilient that way..
var tagreg = /\[(\/?)(b|u|i|s|center|code)]/ig
div.innerHTML="[b][i]helloworld[/b]".replace(tagreg, "<$1$2>") //no closing i
//div.inerHTML=="<b><i>helloworld</i></b>"
AFAIK you can't express recursion with regular expressions.
You can however do that with .NET's System.Text.RegularExpressions using balanced matching. See more here: http://blogs.msdn.com/bclteam/archive/2005/03/15/396452.aspx
If you're using .NET you can probably implement what you need with a callback.
If not, you may have to roll your own little javascript parser.
Then again, if you can afford to hit the server you can use the full parser. :)
What do you need this for, anyway? If it is for anything other than a preview I highly recommend doing the processing server-side.
You could just repeatedly apply the regexp until it no longer matches. That would do odd things like "[b][b]foo[/b][/b]" => "<b>[b]foo</b>[/b]" => "<b><b>foo</b></b>", but as far as I can see the end result will still be a sensible string with matching (though not necessarily properly nested) tags.
Or if you want to do it 'right', just write a simple recursive descent parser. Though people might expect "[b]foo[u]bar[/b]baz[/u]" to work, which is tricky to recognise with a parser.
The reason the nested block doesn't get replaced is because the match, for [b], places the position after [/b]. Thus, everything that ((.){1,}?) matches is then ignored.
It is possible to write a recursive parser in server-side -- Perl uses qr// and Ruby probably has something similar.
Though, you don't necessarily need true recursive. You can use a relatively simple loop to handle the string equivalently:
var s = '[b]hello[/b] [u]world[/u] [b]foo [u]to the[/u] bar[/b]';
var exptags = /\[(b|u|i|s|center|code){1}]((.){1,}?)\[\/(\1){1}]/ig;
while (s.match(exptags)) {
s = s.replace(exptags, "<$1>$2</$1>");
}
document.writeln('<div>' + s + '</div>'); // after
In this case, it'll make 2 passes:
0: [b]hello[/b] [u]world[/u] [b]foo [u]to the[/u] bar[/b]
1: <b>hello</b> <u>world</u> <b>foo [u]to the[/u] bar</b>
2: <b>hello</b> <u>world</u> <b>foo <u>to the</u> bar</b>
Also, a few suggestions for cleaning up the RegEx:
var exptags = /\[(b|u|i|s|center|code)\](.+?)\[\/(\1)\]/ig;
{1} is assumed when no other count specifiers exist
{1,} can be shortened to +
Agree with Richard Szalay, but his regex didn't get quoted right:
var exptags = /\[(b|u|i|s|center|code)](.*)\[\/\1]/ig;
is cleaner. Note that I also change .+? to .*. There are two problems with .+?:
you won't match [u][/u], since there isn't at least one character between them (+)
a non-greedy match won't deal as nicely with the same tag nested inside itself (?)
Yes, you will have to loop. Alternatively since your tags looks so much like HTML ones you could replace [b] for <b> and [/b] for </b> separately. (.){1,}? is the same as (.*?) - that is, any symbols, least possible sequence length.
Updated: Thanks to MrP, (.){1,}? is (.)+?, my bad.
How about:
tagreg=/\[(.?)?(b|u|i|s|center|code)\]/gi;
"[b][i]helloworld[/i][/b]".replace(tagreg, "<$1$2>");
"[b]helloworld[/b]".replace(tagreg, "<$1$2>");
For me the above produces:
<b><i>helloworld</i></b>
<b>helloworld</b>
This appears to do what you want, and has the advantage of needing only a single pass.
Disclaimer: I don't code often in JS, so if I made any mistakes please feel free to point them out :-)
You are right about the inner pattern being troublesome.
((.){1,}?)
That is doing a captured match at least once and then the whole thing is captured. Every character inside your tag will be captured as a group.
You are also capturing your closing element name when you don't need it and are using {1} when that is implied. Below is a cleanup up version:
/\[(b|u|i|s|center|code)](.+?)\[\/\1]/ig
Not sure about the other problem.