endsWith in JavaScript - javascript

How can I check if a string ends with a particular character in JavaScript?
Example: I have a string
var str = "mystring#";
I want to know if that string is ending with #. How can I check it?
Is there a endsWith() method in JavaScript?
One solution I have is take the length of the string and get the last character and check it.
Is this the best way or there is any other way?

UPDATE (Nov 24th, 2015):
This answer is originally posted in the year 2010 (SIX years back.) so please take note of these insightful comments:
Shauna -
Update for Googlers - Looks like ECMA6 adds this function. The MDN article also shows a polyfill. https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
T.J. Crowder -
Creating substrings isn't expensive on modern browsers; it may well have been in 2010 when this answer was posted. These days, the simple this.substr(-suffix.length) === suffix approach is fastest on Chrome, the same on IE11 as indexOf, and only 4% slower (fergetaboutit territory) on Firefox: https://jsben.ch/OJzlM And faster across the board when the result is false: jsperf.com/endswith-stackoverflow-when-false Of course, with ES6 adding endsWith, the point is moot. :-)
ORIGINAL ANSWER:
I know this is a year old question... but I need this too and I need it to work cross-browser so... combining everyone's answer and comments and simplifying it a bit:
String.prototype.endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
Doesn't create a substring
Uses native indexOf function for fastest results
Skip unnecessary comparisons using the second parameter of indexOf to skip ahead
Works in Internet Explorer
NO Regex complications
Also, if you don't like stuffing things in native data structure's prototypes, here's a standalone version:
function endsWith(str, suffix) {
return str.indexOf(suffix, str.length - suffix.length) !== -1;
}
EDIT: As noted by #hamish in the comments, if you want to err on the safe side and check if an implementation has already been provided, you can just adds a typeof check like so:
if (typeof String.prototype.endsWith !== 'function') {
String.prototype.endsWith = function(suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
}

/#$/.test(str)
will work on all browsers, doesn't require monkey patching String, and doesn't require scanning the entire string as lastIndexOf does when there is no match.
If you want to match a constant string that might contain regular expression special characters, such as '$', then you can use the following:
function makeSuffixRegExp(suffix, caseInsensitive) {
return new RegExp(
String(suffix).replace(/[$%()*+.?\[\\\]{|}]/g, "\\$&") + "$",
caseInsensitive ? "i" : "");
}
and then you can use it like this
makeSuffixRegExp("a[complicated]*suffix*").test(str)

Unfortunately not.
if( "mystring#".substr(-1) === "#" ) {}

Come on, this is the correct endsWith implementation:
String.prototype.endsWith = function (s) {
return this.length >= s.length && this.substr(this.length - s.length) == s;
}
using lastIndexOf just creates unnecessary CPU loops if there is no match.

This version avoids creating a substring, and doesn't use regular expressions (some regex answers here will work; others are broken):
String.prototype.endsWith = function(str)
{
var lastIndex = this.lastIndexOf(str);
return (lastIndex !== -1) && (lastIndex + str.length === this.length);
}
If performance is important to you, it would be worth testing whether lastIndexOf is actually faster than creating a substring or not. (It may well depend on the JS engine you're using...) It may well be faster in the matching case, and when the string is small - but when the string is huge it needs to look back through the whole thing even though we don't really care :(
For checking a single character, finding the length and then using charAt is probably the best way.

Didn't see apporach with slice method. So i'm just leave it here:
function endsWith(str, suffix) {
return str.slice(-suffix.length) === suffix
}

From developer.mozilla.org String.prototype.endsWith()
Summary
The endsWith() method determines whether a string ends with the characters of another string, returning true or false as appropriate.
Syntax
str.endsWith(searchString [, position]);
Parameters
searchString :
The characters to be searched for at the end of this string.
position :
Search within this string as if this string were only this long; defaults to this string's actual length, clamped within the range established by this string's length.
Description
This method lets you determine whether or not a string ends with another string.
Examples
var str = "To be, or not to be, that is the question.";
alert( str.endsWith("question.") ); // true
alert( str.endsWith("to be") ); // false
alert( str.endsWith("to be", 19) ); // true
Specifications
ECMAScript Language Specification 6th Edition (ECMA-262)
Browser compatibility

return this.lastIndexOf(str) + str.length == this.length;
does not work in the case where original string length is one less than search string length and the search string is not found:
lastIndexOf returns -1, then you add search string length and you are left with the original string's length.
A possible fix is
return this.length >= str.length && this.lastIndexOf(str) + str.length == this.length

if( ("mystring#").substr(-1,1) == '#' )
-- Or --
if( ("mystring#").match(/#$/) )

Just another quick alternative that worked like a charm for me, using regex:
// Would be equivalent to:
// "Hello World!".endsWith("World!")
"Hello World!".match("World!$") != null

String.prototype.endsWith = function(str)
{return (this.match(str+"$")==str)}
String.prototype.startsWith = function(str)
{return (this.match("^"+str)==str)}
I hope this helps
var myStr = “ Earth is a beautiful planet ”;
var myStr2 = myStr.trim();
//==“Earth is a beautiful planet”;
if (myStr2.startsWith(“Earth”)) // returns TRUE
if (myStr2.endsWith(“planet”)) // returns TRUE
if (myStr.startsWith(“Earth”))
// returns FALSE due to the leading spaces…
if (myStr.endsWith(“planet”))
// returns FALSE due to trailing spaces…
the traditional way
function strStartsWith(str, prefix) {
return str.indexOf(prefix) === 0;
}
function strEndsWith(str, suffix) {
return str.match(suffix+"$")==suffix;
}

I don't know about you, but:
var s = "mystring#";
s.length >= 1 && s[s.length - 1] == '#'; // will do the thing!
Why regular expressions? Why messing with the prototype? substr? c'mon...

I just learned about this string library:
http://stringjs.com/
Include the js file and then use the S variable like this:
S('hi there').endsWith('hi there')
It can also be used in NodeJS by installing it:
npm install string
Then requiring it as the S variable:
var S = require('string');
The web page also has links to alternate string libraries, if this one doesn't take your fancy.

If you're using lodash:
_.endsWith('abc', 'c'); // true
If not using lodash, you can borrow from its source.

function strEndsWith(str,suffix) {
var reguex= new RegExp(suffix+'$');
if (str.match(reguex)!=null)
return true;
return false;
}

So many things for such a small problem, just use this Regular Expression
var str = "mystring#";
var regex = /^.*#$/
if (regex.test(str)){
//if it has a trailing '#'
}

Its been many years for this question. Let me add an important update for the users who wants to use the most voted chakrit's answer.
'endsWith' functions is already added to JavaScript as part of ECMAScript 6 (experimental technology)
Refer it here: https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/String/endsWith
Hence it is highly recommended to add check for the existence of native implementation as mentioned in the answer.

function check(str)
{
var lastIndex = str.lastIndexOf('/');
return (lastIndex != -1) && (lastIndex == (str.length - 1));
}

A way to future proof and/or prevent overwriting of existing prototype would be test check to see if it has already been added to the String prototype. Here's my take on the non-regex highly rated version.
if (typeof String.endsWith !== 'function') {
String.prototype.endsWith = function (suffix) {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
};
}

#chakrit's accepted answer is a solid way to do it yourself. If, however, you're looking for a packaged solution, I recommend taking a look at underscore.string, as #mlunoe pointed out. Using underscore.string, the code would be:
function endsWithHash(str) {
return _.str.endsWith(str, '#');
}

After all those long tally of answers, i found this piece of code simple and easy to understand!
function end(str, target) {
return str.substr(-target.length) == target;
}

if you dont want to use lasIndexOf or substr then why not just look at the string in its natural state (ie. an array)
String.prototype.endsWith = function(suffix) {
if (this[this.length - 1] == suffix) return true;
return false;
}
or as a standalone function
function strEndsWith(str,suffix) {
if (str[str.length - 1] == suffix) return true;
return false;
}

String.prototype.endWith = function (a) {
var isExp = a.constructor.name === "RegExp",
val = this;
if (isExp === false) {
a = escape(a);
val = escape(val);
} else
a = a.toString().replace(/(^\/)|(\/$)/g, "");
return eval("/" + a + "$/.test(val)");
}
// example
var str = "Hello";
alert(str.endWith("lo"));
alert(str.endWith(/l(o|a)/));

This builds on #charkit's accepted answer allowing either an Array of strings, or string to passed in as an argument.
if (typeof String.prototype.endsWith === 'undefined') {
String.prototype.endsWith = function(suffix) {
if (typeof suffix === 'String') {
return this.indexOf(suffix, this.length - suffix.length) !== -1;
}else if(suffix instanceof Array){
return _.find(suffix, function(value){
console.log(value, (this.indexOf(value, this.length - value.length) !== -1));
return this.indexOf(value, this.length - value.length) !== -1;
}, this);
}
};
}
This requires underscorejs - but can probably be adjusted to remove the underscore dependency.

if(typeof String.prototype.endsWith !== "function") {
/**
* String.prototype.endsWith
* Check if given string locate at the end of current string
* #param {string} substring substring to locate in the current string.
* #param {number=} position end the endsWith check at that position
* #return {boolean}
*
* #edition ECMA-262 6th Edition, 15.5.4.23
*/
String.prototype.endsWith = function(substring, position) {
substring = String(substring);
var subLen = substring.length | 0;
if( !subLen )return true;//Empty string
var strLen = this.length;
if( position === void 0 )position = strLen;
else position = position | 0;
if( position < 1 )return false;
var fromIndex = (strLen < position ? strLen : position) - subLen;
return (fromIndex >= 0 || subLen === -fromIndex)
&& (
position === 0
// if position not at the and of the string, we can optimise search substring
// by checking first symbol of substring exists in search position in current string
|| this.charCodeAt(fromIndex) === substring.charCodeAt(0)//fast false
)
&& this.indexOf(substring, fromIndex) === fromIndex
;
};
}
Benefits:
This version is not just re-using indexOf.
Greatest performance on long strings. Here is a speed test http://jsperf.com/starts-ends-with/4
Fully compatible with ecmascript specification. It passes the tests

Do not use regular expressions. They are slow even in fast languages. Just write a function that checks the end of a string. This library has nice examples: groundjs/util.js.
Be careful adding a function to String.prototype. This code has nice examples of how to do it: groundjs/prototype.js
In general, this is a nice language-level library: groundjs
You can also take a look at lodash

all of them are very useful examples. Adding String.prototype.endsWith = function(str) will help us to simply call the method to check if our string ends with it or not, well regexp will also do it.
I found a better solution than mine. Thanks every one.

For coffeescript
String::endsWith = (suffix) ->
-1 != #indexOf suffix, #length - suffix.length

This is the implementation of endsWith:
String.prototype.endsWith = function (str) {
return (this.length >= str.length) && (this.substr(this.length - str.length) === str);
}

7 years old post, but I was not able to understand top few posts, because they are complex. So, I wrote my own solution:
function strEndsWith(str, endwith)
{
var lastIndex = url.lastIndexOf(endsWith);
var result = false;
if (lastIndex > 0 && (lastIndex + "registerc".length) == url.length)
{
result = true;
}
return result;
}

Related

Javascript find and match last item of the string

I am trying tor write this function that Check if a string (first argument, str) ends with the given target string (second argument, target). I have used this code but it seems not to work. How can i tweak it?
function confirmEnding(str, target) {
var last = str.substring(-1);
var last2 = target.substring(-1);
if (last == last2) return true;
else if (last !== last2) return false;
}
confirmEnding("Walking on water and developing software from a specification
are easy if both are frozen", "specification") )/*should return "false".
confirmEnding("Bastian", "n") should return true.
confirmEnding("Connor", "n") should return false.
confirmEnding("Walking on water and developing software from a specification
are easy if both are frozen", "specification") should return false.
confirmEnding("He has to give me a new name", "name") should return true.
confirmEnding("Open sesame", "same") should return true.
confirmEnding("Open sesame", "pen") should return false.
confirmEnding("If you want to save our world, you must hurry. We dont know
how much longer we can withstand the nothing", "mountain") should return
false.
Do not use the built-in method .endsWith() to solve the challenge.*/
In order to pass all of the tests with the desired return values, the function should not be comparing the last character of the string, but rather the entire string, target to the corresponding end substring of str. You need the length of target to find the correct starting index for the corresponding substring in str as follows:
function confirmEnding (str, target) {
return str.substr(-(target.length)) === target
}
Your code is comparing the entire strings. See substring() documentation below. -1 is defaulting to 0 thus returning the substring starting at index 0 and returning the rest of the string (the entire string) since no end index is given. .
"If either argument is less than 0 or is NaN, it is treated as if it
were 0."
You can use the substr() method instead of substring() if you want to use negative indices. substr() recognizes negative index values instead of defaulting to 0.
"If start is negative, substr() uses it as a character index from the
end of the string."
You can use the length of target and subtract it from the length of str to get the correct substring for comparison. This will return all of the characters from this index to the end of the string as in str.length - target.lengththough you only really need target.length to make the comparison using negative indices.
Using substring():
function confirmEnding (str, target) {
var last = str.substring(str.length-(target.length));
if (last == target ) return true;
else return false;
}
Using substr():
function confirmEnding (str, target) {
var last = str.substr(-(target.length));
if (last == target ) return true;
else return false;
}
or a cleaner/alternate implementation:
function confirmEnding (str, target) {
return str.substr(-(target.length) === target)
}
substr() documentation
substring() documentation
After seeing the ongoing confusion over this case (abbreviated for readability):
confirmEnding(
"Walking on water...both are frozen",
"specification"
); // Should return false (why not true?)
and also this interesting note:
/* Do not use the built-in method .endsWith() to solve the challenge. */
I have a hunch about what may have happened.
Double-check the instructions for this question. Are you sure you're supposed to test if the last character of each string is the same? It sounds like you are supposed to test if the src string ends with the entire target string.
After all, that is what the .endsWith() method does. And it explains the mystery of the test case above.
The MDN documentation for .endsWith() doesn't describe the method very well, but the examples it gives make it clear.
With that understanding, you can probably now write the code. I'm not going to write it for you, but I will drop some hints below. I added some code for your tests so that they not only log the result, but also whether they return the desired result. (In the version as written here, all the tests will fail.)
// Return true if str ends with target, false if it does not
function confirmEnding( str, target ) {
// You can do this in a single return statement
// with one === comparison in it. The .slice()
// method will help you here, and you only need
// to pass a single argument into it.
// You don't need any if statements, intermediate
// variables, or anything fancy.
// There are several other ways to do it too, including
// the approach shown on the MDN page.
}
function testEnding( str, target, desired ) {
var result = confirmEnding( str, target );
console.log(
'"' + str + '"',
'"' + target + '"',
'returns', result,
result === desired ? 'Good' : 'WRONG!'
);
}
testEnding( "Bastian", "n", true );
testEnding( "Connor", "n", false );
testEnding( "Walking on water and developing software from a specification are easy if both are frozen", "specification", false );
testEnding( "He has to give me a new name", "name", true );
testEnding( "Open sesame", "same", true );
testEnding( "Open sesame", "pen", false );
testEnding( "If you want to save our world, you must hurry ); We dont know how much longer we can withstand the nothing", "mountain", false );
You can use this function:
function confirmEnding(a, b) {
var l1 = a[a.length - 1];
var l2 = b[b.length - 1];
return l1 === l2;
}
Your error is that you're using substring. Try str.substr instead of substring
function confirmEnding (str, target) {
return str.substr(-1) == target.substr(-1);
}
console.log(confirmEnding("Walking on water and developing software from a specification are easy if both are frozen", "specification"));
const a = "Walking on water and developing software from a specification are easy if both are frozen",
b = "specification";
// your function
const equalLastLetter = (a, b) => a.substr(-1) === b.substr(-1);
console.log(equalLastLetter(a, b))
How about this?
function confirmEnding (str, target) {
var last = str.charAt(str.length-1);
var last2 = target.charAt(target.length-1);
return (last == last2);
}
You can use chatAt()
function confirmEnding (str, target) {
var last = str.charAt(str.length -1);
var last2 = target.charAt(target.length -1);
return last === last2 ;
}
Why have to check if last words are same so:
const confirmEnding = (str, target) => new RegExp(`${target}$`, '').test(str)
console.log(confirmEnding("Walking on water and developing software from a specification are easy if both are frozen", "specification"))
console.log(confirmEnding("Bastian", "n"))
console.log(confirmEnding("Connor", "n"))
console.log(confirmEnding("Walking on water and developing software from a specification are easy if both are frozen", "specification"))
console.log(confirmEnding("He has to give me a new name", "name"))
console.log(confirmEnding("Open sesame", "same"))
console.log(confirmEnding("Open sesame", "pen"))
console.log(confirmEnding("If you want to save our world, you must hurry. We dont know how much longer we can withstand the nothing", "mountain"))
Simplest way:
const confirmEnding = (_str, _target) => _str.charAt(_str.length - 1) === _target.charAt(_target.length - 1);
https://jsfiddle.net/pablodarde/hsdgjmzw/

indexOf is not working in JavaScript

I am checking an index Of string in JAVASCRIPT. and this is coming as false. where as the value does belong to it as below :
if(idOfControl.indexOf(idOfButton)) == is giving false for the below values.
idOfControl = "dlInventory_btnEditComment_0"
idOfButton = "dlInventory_btnEditComment"
But if I run idOfControl.replace(idOfButton, ""); It is working and replacing the text.
Any reason for this?
indexOf can also return 0, in the event of your string being found at the position 0. 0 evaluates to false. Try:
if(idOfControl.indexOf(idOfButton) > -1)
More info: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/indexOf
There are these three big options:
indexOf > -1
The result of indexOf can be 0 meaning that the string was found at the beginning of the string. When string is not found, the return value is -1, therefore:
if (idOfControl.indexOf(idOfButton) > -1) {
// Do something
}
Which can be nicer written as #paxdiablo commented:
if (idOfControl.indexOf(idOfButton) >= 0) {
// Do something
}
via regex
You can use a very simple regular expression to test your match.
var idOfControl = "dlInventory_btnEditComment_0"
var control = /dlInventory_btnEditComment/;
if (idOfControl.test(control)) {
// do something
}
This approach can be enhanced to capture the last number of your string (if you need it)
var idOfControl = "dlInventory_btnEditComment_0"
var control = /dlInventory_btnEditComment_(\d+)/;
var match = control.exec(idOfControl);
if (match) {
alert('the number found is: ' + match[1]);
}
You can try it out here: http://jsfiddle.net/4Z9UC/
via indexOf in a hacky way
This uses a bitwise operator to return a truthy value when the position is !=-1 (In two's complement notation, -1 is internally represented as 111...111, and its inversion is 000...000 which is 0, i.e. a falsy value). It is in fact more efficient than the >-1 option, but it is harder to read and to understand. (EDIT: this became so popular that you can say it is a standard)
if (~idOfControl.indexOf(idOfButton)) {
// do something
}

Changing the RegExp flags

So basically I wrote myself this function so as to be able to count the number of occurances of a Substring in a String:
String.prototype.numberOf = function(needle) {
var num = 0,
lastIndex = 0;
if(typeof needle === "string" || needle instanceof String) {
while((lastIndex = this.indexOf(needle, lastIndex) + 1) > 0)
{num++;} return num;
} else if(needle instanceof RegExp) {
// needle.global = true;
return this.match(needle).length;
} return 0;
};
The method itself performs rather well and both the RegExp and String based searches are quite comparable as to the execution time (both ~2ms on the entire vast Ray Bradbury's "451 Fahrenheit" searching for all the "the"s).
What sort of bothers me, though, is the impossibility of changing the flag of the supplied RegExp instance. There is no point in calling String.prototype.match in this function without the global flag of the supplied Regular Expression set to true, as it would only note the first occurance then. You could certainly set the flag manually on each RegExp passed to the function, I'd however prefer being able to clone and then manipulate the supplied Regular Expression's flags.
Astonishingly enough, I'm not permitted to do so as the RegExp.prototype.global flag (more precisely all flags) appear to be read-only. Thence the commented-out line 8.
So my question is: Is there a nice way of changing the flags of a RegExp object?
I don't really wanna do stuff like this:
if(!expression.global)
expression = eval(expression.toString() + "g");
Some implementations might not event support the RegExp.prototype.toString and simply inherit it from the Object.prototype, or it could be a different formatting entirely. And it just seems as a bad coding practice to begin with.
First, your current code does not work correctly when needle is a regex which does not match. i.e. The following line:
return this.match(needle).length;
The match method returns null when there is no match. A JavaScript error is then generated when the length property of null is (unsuccessfully) accessed. This is easily fixed like so:
var m = this.match(needle);
return m ? m.length : 0;
Now to the problem at hand. You are correct when you say that global, ignoreCase and multiline are read only properties. The only option is to create a new RegExp. This is easily done since the regex source string is stored in the re.source property. Here is a tested modified version of your function which corrects the problem above and creates a new RegExp object when needle does not already have its global flag set:
String.prototype.numberOf = function(needle) {
var num = 0,
lastIndex = 0;
if (typeof needle === "string" || needle instanceof String) {
while((lastIndex = this.indexOf(needle, lastIndex) + 1) > 0)
{num++;} return num;
} else if(needle instanceof RegExp) {
if (!needle.global) {
// If global flag not set, create new one.
var flags = "g";
if (needle.ignoreCase) flags += "i";
if (needle.multiline) flags += "m";
needle = RegExp(needle.source, flags);
}
var m = this.match(needle);
return m ? m.length : 0;
}
return 0;
};
var globalRegex = new RegExp(needle.source, "g");
Live Demo EDIT: The m was only for the sake of demonstrating that you can set multiple modifiers
var regex = /find/;
var other = new RegExp(regex.source, "gm");
alert(other.global);
alert(other.multiline);
r = new Regexp(r.source, r.flags + (r.global ? "" : "g"));
There isn't much you can do but I highly recommend you avoid using eval. You can extend the RegExp prototype to help you out.
RegExp.prototype.flags = function () {
return (this.ignoreCase ? "i" : "")
+ (this.multiline ? "m" : "")
+ (this.global ? "g" : "");
};
var reg1 = /AAA/i;
var reg2 = new RegExp(reg1.source, reg1.flags() + 'g');

Count number of matches of a regex in Javascript

I wanted to write a regex to count the number of spaces/tabs/newline in a chunk of text. So I naively wrote the following:-
numSpaces : function(text) {
return text.match(/\s/).length;
}
For some unknown reasons it always returns 1. What is the problem with the above statement? I have since solved the problem with the following:-
numSpaces : function(text) {
return (text.split(/\s/).length -1);
}
tl;dr: Generic Pattern Counter
// THIS IS WHAT YOU NEED
const count = (str) => {
const re = /YOUR_PATTERN_HERE/g
return ((str || '').match(re) || []).length
}
For those that arrived here looking for a generic way to count the number of occurrences of a regex pattern in a string, and don't want it to fail if there are zero occurrences, this code is what you need. Here's a demonstration:
/*
* Example
*/
const count = (str) => {
const re = /[a-z]{3}/g
return ((str || '').match(re) || []).length
}
const str1 = 'abc, def, ghi'
const str2 = 'ABC, DEF, GHI'
console.log(`'${str1}' has ${count(str1)} occurrences of pattern '/[a-z]{3}/g'`)
console.log(`'${str2}' has ${count(str2)} occurrences of pattern '/[a-z]{3}/g'`)
Original Answer
The problem with your initial code is that you are missing the global identifier:
>>> 'hi there how are you'.match(/\s/g).length;
4
Without the g part of the regex it will only match the first occurrence and stop there.
Also note that your regex will count successive spaces twice:
>>> 'hi there'.match(/\s/g).length;
2
If that is not desirable, you could do this:
>>> 'hi there'.match(/\s+/g).length;
1
As mentioned in my earlier answer, you can use RegExp.exec() to iterate over all matches and count each occurrence; the advantage is limited to memory only, because on the whole it's about 20% slower than using String.match().
var re = /\s/g,
count = 0;
while (re.exec(text) !== null) {
++count;
}
return count;
(('a a a').match(/b/g) || []).length; // 0
(('a a a').match(/a/g) || []).length; // 3
Based on https://stackoverflow.com/a/48195124/16777 but fixed to actually work in zero-results case.
Here is a similar solution to #Paolo Bergantino's answer, but with modern operators. I'll explain below.
const matchCount = (str, re) => {
return str?.match(re)?.length ?? 0;
};
// usage
let numSpaces = matchCount(undefined, /\s/g);
console.log(numSpaces); // 0
numSpaces = matchCount("foobarbaz", /\s/g);
console.log(numSpaces); // 0
numSpaces = matchCount("foo bar baz", /\s/g);
console.log(numSpaces); // 2
?. is the optional chaining operator. It allows you to chain calls as deep as you want without having to worry about whether there is an undefined/null along the way. Think of str?.match(re) as
if (str !== undefined && str !== null) {
return str.match(re);
} else {
return undefined;
}
This is slightly different from #Paolo Bergantino's. Theirs is written like this: (str || ''). That means if str is falsy, return ''. 0 is falsy. document.all is falsy. In my opinion, if someone were to pass those into this function as a string, it would probably be because of programmer error. Therefore, I'd rather be informed I'm doing something non-sensible than troubleshoot why I keep on getting a length of 0.
?? is the nullish coalescing operator. Think of it as || but more specific. If the left hand side of || evaluates to falsy, it executes the right-hand side. But ?? only executes if the left-hand side is undefined or null.
Keep in mind, the nullish coalescing operator in ?.length ?? 0 will return the same thing as using ?.length || 0. The difference is, if length returns 0, it won't execute the right-hand side... but the result is going to be 0 whether you use || or ??.
Honestly, in this situation I would probably change it to || because more JavaScript developers are familiar with that operator. Maybe someone could enlighten me on benefits of ?? vs || in this situation, if any exist.
Lastly, I changed the signature so the function can be used for any regex.
Oh, and here is a typescript version:
const matchCount = (str: string, re: RegExp) => {
return str?.match(re)?.length ?? 0;
};
('my string'.match(/\s/g) || []).length;
This is certainly something that has a lot of traps. I was working with Paolo Bergantino's answer, and realising that even that has some limitations. I found working with string representations of dates a good place to quickly find some of the main problems. Start with an input string like this:
'12-2-2019 5:1:48.670'
and set up Paolo's function like this:
function count(re, str) {
if (typeof re !== "string") {
return 0;
}
re = (re === '.') ? ('\\' + re) : re;
var cre = new RegExp(re, 'g');
return ((str || '').match(cre) || []).length;
}
I wanted the regular expression to be passed in, so that the function is more reusable, secondly, I wanted the parameter to be a string, so that the client doesn't have to make the regex, but simply match on the string, like a standard string utility class method.
Now, here you can see that I'm dealing with issues with the input. With the following:
if (typeof re !== "string") {
return 0;
}
I am ensuring that the input isn't anything like the literal 0, false, undefined, or null, none of which are strings. Since these literals are not in the input string, there should be no matches, but it should match '0', which is a string.
With the following:
re = (re === '.') ? ('\\' + re) : re;
I am dealing with the fact that the RegExp constructor will (I think, wrongly) interpret the string '.' as the all character matcher \.\
Finally, because I am using the RegExp constructor, I need to give it the global 'g' flag so that it counts all matches, not just the first one, similar to the suggestions in other posts.
I realise that this is an extremely late answer, but it might be helpful to someone stumbling along here. BTW here's the TypeScript version:
function count(re: string, str: string): number {
if (typeof re !== 'string') {
return 0;
}
re = (re === '.') ? ('\\' + re) : re;
const cre = new RegExp(re, 'g');
return ((str || '').match(cre) || []).length;
}
Using modern syntax avoids the need to create a dummy array to count length 0
const countMatches = (exp, str) => str.match(exp)?.length ?? 0;
Must pass exp as RegExp and str as String.
how about like this
function isint(str){
if(str.match(/\d/g).length==str.length){
return true;
}
else {
return false
}
}

Trim string in JavaScript

How do I remove all whitespace from the start and end of the string?
All browsers since IE9+ have trim() method for strings:
" \n test \n ".trim(); // returns "test" here
For those browsers who does not support trim(), you can use this polyfill from MDN:
if (!String.prototype.trim) {
(function() {
// Make sure we trim BOM and NBSP
var rtrim = /^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g;
String.prototype.trim = function() {
return this.replace(rtrim, '');
};
})();
}
That said, if using jQuery, $.trim(str) is also available and handles undefined/null.
See this:
String.prototype.trim=function(){return this.replace(/^\s+|\s+$/g, '');};
String.prototype.ltrim=function(){return this.replace(/^\s+/,'');};
String.prototype.rtrim=function(){return this.replace(/\s+$/,'');};
String.prototype.fulltrim=function(){return this.replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g,'').replace(/\s+/g,' ');};
The trim from jQuery is convenient if you are already using that framework.
$.trim(' your string ');
I tend to use jQuery often, so trimming strings with it is natural for me. But it's possible that there is backlash against jQuery out there? :)
Although there are a bunch of correct answers above, it should be noted that the String object in JavaScript has a native .trim() method as of ECMAScript 5. Thus ideally any attempt to prototype the trim method should really check to see if it already exists first.
if(!String.prototype.trim){
String.prototype.trim = function(){
return this.replace(/^\s+|\s+$/g,'');
};
}
Added natively in:
JavaScript 1.8.1 / ECMAScript 5
Thus supported in:
Firefox: 3.5+
Safari: 5+
Internet Explorer: IE9+ (in Standards mode only!) http://blogs.msdn.com/b/ie/archive/2010/06/25/enhanced-scripting-in-ie9-ecmascript-5-support-and-more.aspx
Chrome: 5+
Opera: 10.5+
ECMAScript 5 Support Table: http://kangax.github.com/es5-compat-table/
There are a lot of implementations that can be used. The most obvious seems to be something like this:
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g, "");
};
" foo bar ".trim(); // "foo bar"
Simple version here What is a general function for JavaScript trim?
function trim(str) {
return str.replace(/^\s+|\s+$/g,"");
}
I know this question has been asked three years back.Now,String.trim() was added natively in JavaScript.For an instance, you can trim directly as following,
document.getElementById("id").value.trim();
If you are using jQuery, use the jQuery.trim() function. For example:
if( jQuery.trim(StringVariable) == '')
Flagrant Badassery has 11 different trims with benchmark information:
http://blog.stevenlevithan.com/archives/faster-trim-javascript
Non-surprisingly regexp-based are slower than traditional loop.
Here is my personal one. This code is old! I wrote it for JavaScript1.1 and Netscape 3 and it has been only slightly updated since. (Original used String.charAt)
/**
* Trim string. Actually trims all control characters.
* Ignores fancy Unicode spaces. Forces to string.
*/
function trim(str) {
str = str.toString();
var begin = 0;
var end = str.length - 1;
while (begin <= end && str.charCodeAt(begin) < 33) { ++begin; }
while (end > begin && str.charCodeAt(end) < 33) { --end; }
return str.substr(begin, end - begin + 1);
}
Use the Native JavaScript Methods: String.trimLeft(), String.trimRight(), and String.trim().
String.trim() is supported in IE9+ and all other major browsers:
' Hello '.trim() //-> 'Hello'
String.trimLeft() and String.trimRight() are non-standard, but are supported in all major browsers except IE
' Hello '.trimLeft() //-> 'Hello '
' Hello '.trimRight() //-> ' Hello'
IE support is easy with a polyfill however:
if (!''.trimLeft) {
String.prototype.trimLeft = function() {
return this.replace(/^\s+/,'');
};
String.prototype.trimRight = function() {
return this.replace(/\s+$/,'');
};
if (!''.trim) {
String.prototype.trim = function() {
return this.replace(/^\s+|\s+$/g, '');
};
}
}
String.prototype.trim = String.prototype.trim || function () {
return this.replace(/^\s+|\s+$/g, "");
};
String.prototype.trimLeft = String.prototype.trimLeft || function () {
return this.replace(/^\s+/, "");
};
String.prototype.trimRight = String.prototype.trimRight || function () {
return this.replace(/\s+$/, "");
};
String.prototype.trimFull = String.prototype.trimFull || function () {
return this.replace(/(?:(?:^|\n)\s+|\s+(?:$|\n))/g, "").replace(/\s+/g, " ");
};
Shamelessly stolen from Matt duereg.
Trim code from angular js project
var trim = (function() {
// if a reference is a `String`.
function isString(value){
return typeof value == 'string';
}
// native trim is way faster: http://jsperf.com/angular-trim-test
// but IE doesn't have it... :-(
// TODO: we should move this into IE/ES5 polyfill
if (!String.prototype.trim) {
return function(value) {
return isString(value) ?
value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
};
}
return function(value) {
return isString(value) ? value.trim() : value;
};
})();
and call it as trim(" hello ")
use simply code
var str = " Hello World! ";
alert(str.trim());
Browser support
Feature Chrome Firefox Internet Explorer Opera Safari Edge
Basic support (Yes) 3.5 9 10.5 5 ?
For old browser add prototype
if (!String.prototype.trim) {
String.prototype.trim = function () {
return this.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, '');
};
}
Here's a very simple way:
function removeSpaces(string){
return string.split(' ').join('');
}
I have a lib that uses trim. so solved it by using the following code.
String.prototype.trim = String.prototype.trim || function(){ return jQuery.trim(this); };
I had written this function for trim, when the .trim() function was not available in JS way back in 2008. Some of the older browsers still do not support the .trim() function and i hope this function may help somebody.
TRIM FUNCTION
function trim(str)
{
var startpatt = /^\s/;
var endpatt = /\s$/;
while(str.search(startpatt) == 0)
str = str.substring(1, str.length);
while(str.search(endpatt) == str.length-1)
str = str.substring(0, str.length-1);
return str;
}
Explanation: The function trim() accept a string object and remove any starting and trailing whitespaces (spaces,tabs and newlines) and return the trimmed string. You can use this function to trim form inputs to ensure valid data to be sent.
The function can be called in the following manner as an example.
form.elements[i].value = trim(form.elements[i].value);
You can do it using the plain JavaScript:
function trimString(str, maxLen) {
if (str.length <= maxLen) {
return str;
}
var trimmed = str.substr(0, maxLen);
return trimmed.substr(0, trimmed.lastIndexOf(' ')) + '…';
}
// Let's test it
sentenceOne = "too short";
sentencetwo = "more than the max length";
console.log(trimString(sentenceOne, 15));
console.log(trimString(sentencetwo, 15));
Don't know what bugs can hide here, but I use this:
var some_string_with_extra_spaces=" goes here "
console.log(some_string_with_extra_spaces.match(/\S.*\S|\S/)[0])
Or this, if text contain enters:
console.log(some_string_with_extra_spaces.match(/\S[\s\S]*\S|\S/)[0])
Another try:
console.log(some_string_with_extra_spaces.match(/^\s*(.*?)\s*$/)[1])
Here it is in TypeScript:
var trim: (input: string) => string = String.prototype.trim
? ((input: string) : string => {
return (input || "").trim();
})
: ((input: string) : string => {
return (input || "").replace(/^\s+|\s+$/g,"");
})
It will fall back to the regex if the native prototype is not available.
mine uses a single regex to look for cases where trimming is necessary, and uses that regex's results to determine desired substring bounds:
var illmatch= /^(\s*)(?:.*?)(\s*)$/
function strip(me){
var match= illmatch.exec(me)
if(match && (match[1].length || match[2].length)){
me= me.substring(match[1].length, p.length-match[2].length)
}
return me
}
the one design decision that went into this was using a substring to perform the final capture. s/\?:// (make the middle term capturing) and and the replacement fragment becomes:
if(match && (match[1].length || match[3].length)){
me= match[2]
}
there's two performance bets I made in these impls:
does the substring implementation copy the original string's data? if so, in the first, when a string needs to be trimmed there is a double traversal, first in the regex (which may, hopefully be partial), and second in the substring extraction. hopefully a substring implementation only references the original string, so operations like substring can be nearly free. cross fingers
how good is the capture in the regex impl? the middle term, the output value, could potentially be very long. i wasn't ready to bank that all regex impls' capturing wouldn't balk at a couple hundred KB input capture, but i also did not test (too many runtimes, sorry!). the second ALWAYS runs a capture; if your engine can do this without taking a hit, perhaps using some of the above string-roping-techniques, for sure USE IT!
For IE9+ and other browsers
function trim(text) {
return (text == null) ? '' : ''.trim.call(text);
}

Categories

Resources