Two equal strings representing whitespaces not equals in JS - javascript

I am encountering a problem trying to replace whitespaces in a number.
For instance, this works, i.e. it returns 27721 as expected:
alert("27 721".replace(/ /g, ""));
While - I don't know why - this does not (my browser is in french so thousand separator is a whitespace) :
function getThousandSeparator() {
var testN = 1000;
return testN.toLocaleString().replace(/\d/g,"");
}
alert("27 721".replace(new RegExp(getThousandSeparator(), "g"), ""));
And if I make the function directly return " " then it works.
Also, if you test :
console.log(getThousandSeparator() == " ");
it shows false...
Thank you in advance.

In my testing, the separator character is actually an (non-breaking space), not a real space.

Related

How to check if a string contains a WORD in javascript? [duplicate]

This question already has answers here:
How to check if a string contain specific words?
(11 answers)
Closed 3 years ago.
So, you can easily check if a string contains a particular substring using the .includes() method.
I'm interested in finding if a string contains a word.
For example, if I apply a search for "on" for the string, "phones are good", it should return false. And, it should return true for "keep it on the table".
You first need to convert it into array using split() and then use includes()
string.split(" ").includes("on")
Just need to pass whitespace " " to split() to get all words
This is called a regex - regular expression
You can use of 101regex website when you need to work around them (it helps). Words with custom separators aswell.
function checkWord(word, str) {
const allowedSeparator = '\\\s,;"\'|';
const regex = new RegExp(
`(^.*[${allowedSeparator}]${word}$)|(^${word}[${allowedSeparator}].*)|(^${word}$)|(^.*[${allowedSeparator}]${word}[${allowedSeparator}].*$)`,
// Case insensitive
'i',
);
return regex.test(str);
}
[
'phones are good',
'keep it on the table',
'on',
'keep iton the table',
'keep it on',
'on the table',
'the,table,is,on,the,desk',
'the,table,is,on|the,desk',
'the,table,is|the,desk',
].forEach((x) => {
console.log(`Check: ${x} : ${checkWord('on', x)}`);
});
Explaination :
I am creating here multiple capturing groups for each possibily :
(^.*\son$) on is the last word
(^on\s.*) on is the first word
(^on$) on is the only word
(^.*\son\s.*$) on is an in-between word
\s means a space or a new line
const regex = /(^.*\son$)|(^on\s.*)|(^on$)|(^.*\son\s.*$)/i;
console.log(regex.test('phones are good'));
console.log(regex.test('keep it on the table'));
console.log(regex.test('on'));
console.log(regex.test('keep iton the table'));
console.log(regex.test('keep it on'));
console.log(regex.test('on the table'));
You can .split() your string by spaces (\s+) into an array, and then use .includes() to check if the array of strings has your word within it:
const hasWord = (str, word) =>
str.split(/\s+/).includes(word);
console.log(hasWord("phones are good", "on"));
console.log(hasWord("keep it on the table", "on"));
If you are worried about punctuation, you can remove it first using .replace() (as shown in this answer) and then split():
const hasWord = (str, word) =>
str.replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g,"").split(/\s+/).includes(word);
console.log(hasWord("phones are good son!", "on"));
console.log(hasWord("keep it on, the table", "on"));
You can split and then try to find:
const str = 'keep it on the table';
const res = str.split(/[\s,\?\,\.!]+/).some(f=> f === 'on');
console.log(res);
In addition, some method is very efficient as it will return true if any predicate is true.
You can use .includes() and check for the word. To make sure it is a word and not part of another word, verify that the place you found it in is followed by a space, comma, period, etc and also has one of those before it.
A simple version could just be splitting on the whitespace and looking through the resulting array for the word:
"phones are good".split(" ").find(word => word === "on") // undefined
"keep it on the table".split(" ").find(word => word === "on") // "on"
This just splits by whitespace though, when you need parse text (depending on your input) you'll encounter more word delimiters than whitespace. In that case you could use a regex to account for these characters.
Something like:
"Phones are good, aren't they? They are. Yes!".split(/[\s,\?\,\.!]+/)
I would go with the following assumptions:
Words the start of a sentence always have a trailing space.
Words at the end of a sentence always have a preceding space.
Words in the middle of a sentence always have a trailing and preceding space.
Therefore, I would write my code as follows:
function containsWord(word, sentence) {
return (
sentence.startsWith(word.trim() + " ") ||
sentence.endsWith(" " + word.trim()) ||
sentence.includes(" " + word.trim() + " "));
}
console.log(containsWord("test", "This is a test of the containsWord function."));
Try the following -
var mainString = 'codehandbook'
var substr = /hand/
var found = substr.test(mainString)
if(found){
console.log('Substring found !!')
} else {
console.log('Substring not found !!')
}

Regex match cookie value and remove hyphens

I'm trying to extract out a group of words from a larger string/cookie that are separated by hyphens. I would like to replace the hyphens with a space and set to a variable. Javascript or jQuery.
As an example, the larger string has a name and value like this within it:
facility=34222%7CConner-Department-Store;
(notice the leading "C")
So first, I need to match()/find facility=34222%7CConner-Department-Store; with regex. Then break it down to "Conner Department Store"
var cookie = document.cookie;
var facilityValue = cookie.match( REGEX ); ??
var test = "store=874635%7Csomethingelse;facility=34222%7CConner-Department-Store;store=874635%7Csomethingelse;";
var test2 = test.replace(/^(.*)facility=([^;]+)(.*)$/, function(matchedString, match1, match2, match3){
return decodeURIComponent(match2);
});
console.log( test2 );
console.log( test2.split('|')[1].replace(/[-]/g, ' ') );
If I understood it correctly, you want to make a phrase by getting all the words between hyphens and disallowing two successive Uppercase letters in a word, so I'd prefer using Regex in that case.
This is a Regex solution, that works dynamically with any cookies in the same format and extract the wanted sentence from it:
var matches = str.match(/([A-Z][a-z]+)-?/g);
console.log(matches.map(function(m) {
return m.replace('-', '');
}).join(" "));
Demo:
var str = "facility=34222%7CConner-Department-Store;";
var matches = str.match(/([A-Z][a-z]+)-?/g);
console.log(matches.map(function(m) {
return m.replace('-', '');
}).join(" "));
Explanation:
Use this Regex (/([A-Z][a-z]+)-?/g to match the words between -.
Replace any - occurence in the matched words.
Then just join these matches array with white space.
Ok,
first, you should decode this string as follows:
var str = "facility=34222%7CConner-Department-Store;"
var decoded = decodeURIComponent(str);
// decoded = "facility=34222|Conner-Department-Store;"
Then you have multiple possibilities to split up this string.
The easiest way is to use substring()
var solution1 = decoded.substring(decoded.indexOf('|') + 1, decoded.length)
// solution1 = "Conner-Department-Store;"
solution1 = solution1.replace('-', ' ');
// solution1 = "Conner Department Store;"
As you can see, substring(arg1, arg2) returns the string, starting at index arg1 and ending at index arg2. See Full Documentation here
If you want to cut the last ; just set decoded.length - 1 as arg2 in the snippet above.
decoded.substring(decoded.indexOf('|') + 1, decoded.length - 1)
//returns "Conner-Department-Store"
or all above in just one line:
decoded.substring(decoded.indexOf('|') + 1, decoded.length - 1).replace('-', ' ')
If you want still to use a regular Expression to retrieve (perhaps more) data out of the string, you could use something similar to this snippet:
var solution2 = "";
var regEx= /([A-Za-z]*)=([0-9]*)\|(\S[^:\/?#\[\]\#\;\,']*)/;
if (regEx.test(decoded)) {
solution2 = decoded.match(regEx);
/* returns
[0:"facility=34222|Conner-Department-Store",
1:"facility",
2:"34222",
3:"Conner-Department-Store",
index:0,
input:"facility=34222|Conner-Department-Store;"
length:4] */
solution2 = solution2[3].replace('-', ' ');
// "Conner Department Store"
}
I have applied some rules for the regex to work, feel free to modify them according your needs.
facility can be any Word built with alphabetical characters lower and uppercase (no other chars) at any length
= needs to be the char =
34222 can be any number but no other characters
| needs to be the char |
Conner-Department-Store can be any characters except one of the following (reserved delimiters): :/?#[]#;,'
Hope this helps :)
edit: to find only the part
facility=34222%7CConner-Department-Store; just modify the regex to
match facility= instead of ([A-z]*)=:
/(facility)=([0-9]*)\|(\S[^:\/?#\[\]\#\;\,']*)/
You can use cookies.js, a mini framework from MDN (Mozilla Developer Network).
Simply include the cookies.js file in your application, and write:
docCookies.getItem("Connor Department Store");

Javascript regular expression adjustment

Using mootools I have a regex like this:
new RegExp('^([^\\D'+ separator +']+)(\\d{2})');
In a string it inserts the char defined in separator after every 2 characters. I want it to insert only for the last two.
Example:
String Result
123456 12.34.56 // what it does now
123456 1234.56 // what it should do
I don't have much experience with regex so any help or link to a decent tutorial is appreciated.
If your string only consists of digits, isn't this the same as divide by 100?
'' + str / 100
It might depend on locale though ;-)
I can improve this answer if you have more edge cases I can work with.
If you absolutely must just regular expressions, you could always use this:
'123456'.replace(/(.)(\d{2})$/, function($0, $1, $2) {
return $1 + '.' + $2;
});
This would protect you against strings that would otherwise result in NaN, such as 'foo'.
Don't use regex for this:
var str = "123456".split('').reverse().join('');
var x = str.substring(0,2) + '.' + str.substring(2);
var final = x.split('').reverse().join('');
console.log(final);
Live DEMO
Of course you can check if the string length is bigger than 2
if (str.length > 2)
// ...
Or use string slice function:
str ="123456";
str.slice(0, -2) + "." + str.slice(-2);
How does it work?
I'll break it into pieces:
// Start at the beginning of the string grab all the chars
// and stop two chars before the end of the string
str.slice(0, -2)
// Start at two chars before the end of the string, take all the chars until
// the end of the string.
str.slice(-2);
Assume the string always has more than 2 characters:
str.slice(0, -2) + "." + str.slice(-2)
Reference to String.slice.

How to detect string which contains only spaces?

A string length which contains one space is always equal to 1:
alert('My str length: ' + str.length);
The space is a character, so:
str = " ";
alert('My str length:' + str.length); // My str length: 3
How can I make a distinction between an empty string and a string which contains only spaces? How can I detect a string which contain only spaces?
To achieve this you can use a Regular Expression to remove all the whitespace in the string. If the length of the resulting string is 0, then you can be sure the original only contained whitespace. Try this:
var str = " ";
if (!str.replace(/\s/g, '').length) {
console.log('string only contains whitespace (ie. spaces, tabs or line breaks)');
}
The fastest solution would be using the regex prototype function test() and looking for any character that is not a space, tab, or line break \S :
if (!/\S/.test(str)) {
// Didn't find something other than a space which means it's empty
}
In case you have a super long string, it can make a significant difference as it will stop processing as soon as it finds a non-space character.
Similar to Rory's answer, with ECMA 5 you can now just call str.trim().length instead of using a regular expression. If the resulting value is 0 you know you have a string that contains only spaces.
if (!str.trim().length) {
console.log('str is empty!');
}
You can read more about trim here.
Edit: After looking at this a few years later I noticed this could be simplified further. Since the result of trim will either be truthy or falsy you can also do the following:
if (!str.trim()) {
console.log('str is empty!');
}
if(!str.trim()){
console.log('string is empty or only contains spaces');
}
String#trim() removes the whitespace at the start and end of the string. If the string contained only whitespace, it would be empty after trimming, and the empty string is falsey in JavaScript.
If the string might be null or undefined, we need to first check if the string itself is falsey before trimming.
if(!str || !str.trim()){
//str is null, undefined, or contains only spaces
}
This can be simplified using the optional chaining operator.
if(!str?.trim()){
//str is null, undefined, or contains only spaces
}
You can Trim your String value by creating a trim function for your Strings.
String.prototype.trim = function () {
return this.replace(/^\s*/, "").replace(/\s*$/, "");
}
now it will be available for your every String and you can use it as
str.trim().length// Result will be 0
You can also use this method to remove the white spaces at the start and end of the String i.e
" hello ".trim(); // Result will be "hello"
You can do this by simply using trim.
var str = " ";
if (str.trim().length == 0)
{
console.log("Your string contains only white spaces.")
}
Trim your String value by creating a trim function
var text = " ";
if($.trim(text.length == 0){
console.log("Text is empty");
}
else
{
console.log("Text is not empty");
}
If we want to check if string contains only white spaces, then this might be helpful.
const str = ' ';
console.log(/^\s+$/.test(str));
This will log true.
Typecasting to Number can detect whitespace-only strings (if strings containing only zeros can be excluded):
if (+' ' === 0) console.log('is whitespace');
to make this approach also work for empty- and zerostrings like '0' a truthy numerical prefix could be used:
if (Number('1 0') === 1) console.log('is not whitespace');
if (Number('1 ' + ' \n ') === 1) console.log('is whitespace');
but concatenated casting is expensive - leading to this obscure expression:
String(x || '').indexOf('0') < +x
however, performance- and readability wise - trimed-length still wins over regex or casting-magic.
const tests = ['',' ', '\t\n\r','0',' 0 ','x',' 404 '];
tests.filter(x => String(x || '').trim().length === 0); // fastest
tests.filter(x => /^\s*$/.test(x)); // 33% slower
tests.filter(x => +x === 0 && String(x).indexOf('0') === -1); // 40 % slower
tests.filter(x => String(x || '').indexOf('0') < +x); // 50% slower
tests.filter(x => Number('1 ' + x) === 1); // 66% slower
This works in Dart not Javascript. However, when I searched up how to do this with Dart this question came up, so I figured others may need the Dart answer.
String foo = ' ';
if (foo.replaceAll(' ', '').length == 0) {
print('ALL WHITE SPACE');
}
else {
print('NOT ALL WHITE SPACE');
}
To further clarify, the String ' d ' will print 'NOT ALL WHITE SPACE' and the String ' ' will print 'ALL WHITE SPACE'.

Replace leading spaces with in Javascript

I have text like the following, with embedded spaces that show indentation of some xml data:
<Style id="KMLStyler"><br>
<IconStyle><br>
<colorMode>normal</colorMode><br>
I need to use Javascript to replace each LEADING space with
so that it looks like this:
<Style id="KMLStyler"><br>
<IconStyle><br>
<colorMode>normal</colorMode><br>
I have tried a basic replace, but it is matching all spaces, not just the leading ones. I want to leave all the spaces alone except the leading ones. Any ideas?
JavaScript does not have the convenient \G (not even look-behinds), so there's no pure regex-solution for this AFAIK. How about something like this:
function foo() {
var leadingSpaces = arguments[0].length;
var str = '';
while(leadingSpaces > 0) {
str += ' ';
leadingSpaces--;
}
return str;
}
var s = " A B C";
print(s.replace(/^[ \t]+/mg, foo));
which produces:
A B C
Tested here: http://ideone.com/XzLCR
EDIT
Or do it with a anonymous inner function (is it called that?) as commented by glebm in the comments:
var s = " A B C";
print(s.replace(/^[ \t]+/gm, function(x){ return new Array(x.length + 1).join(' ') }));
See that in action here: http://ideone.com/3JU52
Use ^ to anchor your pattern at the beginning of the string, or if you'r dealing with a multiline string (ie: embedded newlines) add \n to your pattern. You will need to match the whole set of leading spaces at once, and then in the replacement check the length of what was matched to figure out how many nbsps to insert.

Categories

Resources