How to find whole substring in string? - javascript

I have a string and I have to check if that string contains defined substring I need to do some work and otherwise, I should return some error.
I have the following code:
function isContains(myString) {
let subString = 'test1234';
if(myString.includes(subString)) {
// to do some work
} else {
// return some error.
}
}
but the problem is if myString = 'my-string-test1-rrr' its condition return true.
How can I get true only in case when the whole subString was included in myString?

Use indexOf() instead.
function isContains(myString) {
let subString = 'test1234';
if(myString.indexOf(subString) > -1) {
// to do some work
} else {
// return some error.
}
}

you can use regex to check if that value is present are not;
example 1
without containing the specific string
var test = 'my-string-test1-rrr';
console.log(' test --- ', test.match(/test1234/g))
example 2
contains the specific string
var test = 'my-string-test1234-rrr';
console.log(' test --- ', test.match(/test1234/g))

It is highly recommended to use includes() over indexOf() and further indexOf returns the index of the occurrence where you would prefer an immediate answer - false / true if that substring is found inside the searched string.
Your function does exactly what you are asking. I would suggest to isolate the retrieval of this function and make it purer like so, then when you have the return boolean value you could utilize it after to run whatever logic you wish. This way you keep this function pure and separate your concerns better.
I also believe it would be easier for you to debug your issue if you isolate this functions like In the example I provided.
function isContains(myString) {
let subString = 'test1234';
let isContains = false;
if(myString.includes(subString)) {
isContains = true;
} else {
isContains = false;
}
return isContains;
}
You could use it like so in a later phase in your code:
const myString = 'my-string-test1-rrr';
let shouldRunOtherLogic = isContains(myString);
if (shouldRunOtherLogic) {
// to do some work
} else {
// return some error.
}
Hope I could help, if there's anything further you may need feel free to let me know.

Related

Check if string is starting with prefix

I would like to check with javascript if array items starts with the word "prefix".
So far I've done something like this:
let array = ["prefix-word1", "prefix-word2"];
array.forEach(function(element) {
if (element.lastIndexOf('prefix', 0) == 0) {
console.log('prefix');
}
}
For some reason I keep get an error that prefix is not defined. Please help.
This one works (check the comments on the code):
let array = ["prefix-word1", "prefix-word2" , "does not start with prefix"];
array.forEach(function(element) {
// Check if the first word is prefix
if (element.indexOf('prefix') == 0) {
console.log('prefix');
console.log(element);
}
});
console.log("Second approach which is not suggested");
array.forEach(function(element) {
// not the correct approach as suggested by #Barmar though it works
if (element.lastIndexOf('prefix',0) == 0) {
console.log('prefix');
console.log(element);
}
});
Try using double quotation marks instead of single like this "prefix" in functions.

JavaScript regular expression having a weird behaviour

I'm currently making a scripting language for a Discord bot I'm maintaining and I'm facing a weird issue. The following code takes a string as input (I think {if:3|=|0|you are|TechRax is} {range:1|100}), uses the match method of the string to get all functions (expression: /\{(.*?):(.*?)\}/g) from the string. Then using a forEach, I process all of these matches then I replace the matched content with the result on the string, using the replace method.
Here is the code I use:
let newString = 'I think {if:3|=|0|you are|TechRax is} {range:1|100}';
const functionPattern = /\{(.*?):(.*?)\}/g;
const foundFunctions = newString.match(functionPattern);
if (!foundFunctions) throw new Error('No function found');
foundFunctions.forEach((fn) => {
const parsedInput = functionPattern.exec(fn); // = null once the second iteration begins... ? only the first one work. Same issue if I invert the function orders (first works, second and + no)
if (!parsedInput || !parsedInput[1] || !parsedInput[2]) return;
try {
/*const customFunction = new (require(`../../Production/Tags/${parsedInput[1]}`))(this.client, context, contextType);
if (!customFunction) return;
const result = customFunction.run(parsedInput[2].split('|'));*/
const result = 'Stack Overflow test';
newString = newString.replace(fn, result);
} catch (e) {
newString = newString.replace(fn, e);
}
});
// Print newString here (depends if you're on browser or node)
In this context, this.client.constants.functionPattern = /\{(.*?):(.*?)\}/g, foundFunctions = ['{if:4|=|0|you are|alien is}', '{range:1|100}'] and newString = 'I think {if:{argslen}|=|0|you are|{args} is} {range:1|100}'.
Now let's start describing the behaviour, the first iteration goes well: the function module gets imported, it gets processed and the final content gets replaced on the string.
The problem concerns the second one (and all others), the exec method of the function expression returns null. I do not understand this at all, first I thought it was a kind of bug with my RegExp, maybe {random:1|100} was not matching but no because it works perfectly on Regexr.com and... the weirdest: if I eval it (/\{(.*?):(.*?)\}/g.exec('{range:1|100}), it doesn't return null but the actual result I expect.
I guess I'm wrong somewhere but after passing some hours on it I still do not get why it isn't working.
I hope you'll be able to help me out, thanks!
If you need any complementary information, I'm here.
The problem is you're defining your regex GLOBAL
but don't reset the internal pointer inside of the loop: myRegex.lastIndex = 0; (see MDN)
alternatively, you could recreate a regex inside of the forEach.
let newString = 'I think {if:3|=|0|you are|TechRax is} {range:1|100}';
let functionPattern = /\{([^}]*):([^}]*)\}/g;
const foundFunctions = newString.match(functionPattern);
if (!foundFunctions)
throw new Error('No function found');
foundFunctions.forEach(fn => {
//const functionPattern = /\{([^}]*):([^}]*)\}/g; // or redeclare
const parsedInput = functionPattern.exec(fn);
if (!parsedInput || !parsedInput[1] || !parsedInput[2]) return;
try {
const result = 'Stack Overflow test';
newString = newString.replace(fn, result);
functionPattern.lastIndex = 0; // reset internal pointer of your regex
} catch (e) {
newString = newString.replace(fn, e);
}
});
console.log(newString);
I almost forgot: I suggest a more robust regex pattern: \{(\[^}\]*):(\[^}\]*)\}
However, your pattern seems to be good enough.

Check if array value is included in string

I'm working on some client side validation for a contact form of sorts, the website currently isn't online so server side isn't relevant.
I am trying to create a 'word filter' to catch on any abusive of obscene language before the form is 'submitted'.
Heres the code, without the obscenities...
function filterInput(str) {
var inputFilter = ['word1', 'word2', 'word3'];
var arrayLength = inputFilter.length;
if (inputFilter.indexOf(str) > - 1) {
// Word caught...
} else {
// Clear...
}
If the user were to enter 'word1', it will catch the word. If the user enters 'word1word2' or 'John is a word3', it doesn't catch it.
I originally had a for loop which worked better, but still wouldn't work without whitespace between words('word1word2').
Any input would be greatly appreciated, I've been searching but nothing quite matches my needs.
EDIT: So I too have come up with a solution, but seeing the varying ways this can be achieved I am curious as to how it works and also why a particular way is better?
Heres what I came up with...
function filterInput(str) {
var inputFilter = ['word1', 'word2', 'word3'];
var arrayLength = inputFilter.length;
for (var i = 0; i < arrayLength; i++) {
if (str.includes(inputFilter[i])) {
window.alert('Message...');
return;
}
}
}
You're looking for some rather than indexOf, since you have to do custom matching:
if (inputFilter.some(function(word) { return str.indexOf(word) != -1; })) {
// Word caught...
} else {
// Clear...
}
Or with an ES2015+ arrow function and String.prototype.includes:
if (inputFilter.some(word => str.includes(word))) {
// Word caught...
} else {
// Clear...
}
some calls the callback repeatedly until the first time it returns a truthy value. If the callback ever returns a truthy value, some returns true; otherwise, some returns false. E.g., it's asking if "some" of the entries match the predicate function. (any may have been a better term, but when adding to the built-ins, the TC39 committee have to do a lot of work to avoid conflicts with libraries and such.)
If you ever need to get back the actual entry, use find which returns the entry or undefined if not found. If you need its index, use findIndex.
Side note: Just beware that it's notoriously complicated to do this well. Beware of the Scunthorpe problem, and of course people will routinely just confuse the sequence of letters or substitute asterisks or similar to defeat filters of this sort...
you can try something like this:-
function filterInput(str) {
var badWords = ['bad', 'worst'];
var isTrue = false;
if(str) {
for (var i = 0; i < badWords.length; i++) {
isTrue = !!(str.replace(/\W|\s/g, '').toLowerCase().indexOf(badWords[i]) + 1);
if(isTrue) break;
}
}
return isTrue;
}

Javascript - check if string is part of a string in an array

I have an array which lists a couple of websites:
var validSites = new Array();
validSites[0] = "example_1.com";
validSites[1] = "example_2.com";
validSites[2] = "example_3.com";
now i have a small script which checks what web address you are on and could return something like this:
example_1.com/something/something_else
now i need to check if that address is one of the valid sites.
so
example_1.com/*ANYTHING*
would pass as correct.
but
exampleshmample.com
would pass as incorrect.
Now i know you can do an indexOf() which can check if a string is part of a string and it would return -1 if false. but how would i check it through the entire array?
P.s - its for a Chrome Extension.
thanks
Here’s an idea:
var str = 'example_1.com/something/something_else';
if( validSites.indexOf( str.split('/')[0] ) > -1 ) {
// is valid
}
Another one is to use regexp on a joined array:
var str = 'example_1.com/something/something_else';
new RegExp('^('+validSites.join('|')+')','i').test(str);
This will also match f.ex example_1.comyoyoyo
if (validStates.indexOf("example_1.com") > -1) {
// Then it's inside your array
}
else {
// Then it's not inside your array
}
I'd go with json notation, if you can switch from an array, in this scenario
var validSites = {
"example_1.com":"valid",
"example_2.com":true,
"example_3.com":1 //you could even start putting paths in here to beef up your check.
};
//..your check function would be:
.....
if(validSites[window.location.hostname]){
return true;
}else{
return false;
}
You can achieve this by looping and setting flag variable, Try this, i am not tested this.
Just i typed the code directly. i think this may help you
var flag =0;
var givenurl='example_1.com/*ANYTHING*';
for(int i=0 i<validSites.length;i++){
if(givenurl.indexOf(validSites[i])){
flag=1 //Found
}
}
if(flag) { //Url Found }else{ //not found }

adding chr to the number Prototype

I have the following function:
var chr = function(X) {
return String.fromCharCode(X)
}
But I would like to use i.chr() instead of chr(i).
Q: How do I add chr() to the number prototype?
Number.prototype.chr = function() {
return String.fromCharCode(this);
}
var n = 33;
console.log(n.chr());
http://jsfiddle.net/CXWeV/
Also, as Bryan points out, the following will work:
console.log((33).chr());
console.log(Number(33).chr());
But, the following does not work:
33.chr();
EDIT: Although, as Gumbo points out, this does:
33..chr();
As well as a check if the property already exists (see Erik's answer for another way to check):
if (!Number.prototype.chr) {
Number.prototype.chr = function() {
return String.fromCharCode(this);
}
}
if (!Number.prototype.hasOwnProperty('chr')) {
Number.prototype.chr = function() {
return String.fromCharCode(this);
};
}
To use this the number must be in a variable or wrapped in parentheses. Be aware that converting a scalar number to a Number object (called boxing) has an overhead. If you are doing the conversion repeatedly on the same value, you'll want to explicitly convert it to an object first with Number().
Note that simply doing String.fromCharCode might be easier or more clear in some situations.
The normal way, really. Note the importance of surrounding the number in parentheses (or storing it in a variable), as a dot would normally indicate a decimal point:
Number.prototype.chr = function () {
return String.fromCharCode(this);
}
alert((97).chr()); // alerts "a"
I'm not sure whether this works in all browsers, but I'm assuming it does.
Interactive Example

Categories

Resources