check if string does not contain values - javascript

I am using indexOf to see if an email contains anything other than a particular text.
For example, I want to check if an email DOES NOT include "usa" after the # symbol, and display an error message.
I was first splitting the text and removing everything before the # symbol:
var validateemailaddress = regcriteria.email.split('#').pop();
Then, I check if the text doesn't include "usa":
if(validateemailaddress.indexOf('usa')){
$('#emailError').show();
}
Something with the above check doesn't seem right. It works - I can enter an email, and if it does not include 'usa', then the error message will show.
Regardless, when I add an additional check, like if the email does not include "can", then the error message shows no matter what.
As follows:
if(validateemailaddress.indexOf('usa') || validateemailaddress.indexOf('can')){
$('#emailError').show();
}
As stated, using the above, the error message will show regardless if the email includes the text or not.
All I want to do is check if the email includes 'usa' or 'can', and if it doesn't, then show the error message.
How can I make this work?

Here is a simple JavaScript function to check if an email address contains 'usa' or 'can'.
function emailValid(email, words) {
// Get the position of # [indexOfAt = 3]
let indexOfAt = email.indexOf('#');
// Get the string after # [strAfterAt = domain.usa]
let strAfterAt = email.substring(indexOfAt + 1);
for (let index in words) {
// Check if the string contains one of the words from words array
if (strAfterAt.includes(words[index])) {
return true;
}
}
// If the email does not contain any word of the words array
// it is an invalid email
return false;
}
let words = ['usa', 'can'];
if (!emailValid('abc#domain.usa', words)) {
console.log("Invalid Email!");
// Here you can show the error message
} else {
console.log("Valid Email!");
}

You can do something like that, using includes:
const validateEmailAdress = (email) => {
const splittedEmail = email.split('#').pop();
return (splittedEmail.includes('usa') || splittedEmail.includes('can'))
}
console.log("Includes usa: ", validateEmailAdress("something#gmail.usa"))
console.log("Includes can: ", validateEmailAdress("something#gmail.can"))
console.log("Does not includes: ", validateEmailAdress("something#gmail.com"))

There are several ways to check, if a string contains/does not contain a substring.
String.prototype.includes
'String'.includes(searchString); // returns true/false
String.prototype.indexOf
// returns values from -1 to last postion of string.
'String'.indexOf(searchString);
// In combination with ~ this can work similar to includes()
// for strings up to 2^31-1 byte length
// returns 0 if string is not found and -pos if found.
~'String'.indexOf(searchString);
With the help of Regular Expressions:
// substring must be escaped to return valid results
new RegExp(escapedSearchString).test('String'); // returns true/false if the search string is found
'String'.match(escapedSearchString); // returns null or an array if found
So overall you can use allmost all methods like:
if ('String'.function(searchString)) {
// 'String' includes search String
} else {
// 'String' does not include search String
}
Or in case of indexOf:
if ('String'.indexOf(searchString) > -1) {
// 'String' includes search String
} else {
// 'String' does not include search String
}
// OR
if (~'String'.indexOf(searchString)) {
// 'String' includes search String
} else {
// 'String' does not include search String
}

I believe this regular expression match is what you're looking for
System.out.println(myString.matches("(.)#(.)usa(.*)"));

Related

Alternative to message.content.startWith

I'm working with a discord bot and I'm doing a help command with pages.
I have this set up:
if(message.content.startWith(`${prefix}help`))
and
if(message.content.startWith(`${prefix}help 2`))
If i do >help 2 I get both. Is there any way to stop that from happening?
When using startsWith(">help") (not startWith) it will match ">help 2" because that string does indeed start with ">help". If you want to match these cases more precisely you should put the most specific cases first and use else if for subsequent comparisons.
if (message.content.startsWith(`${prefix}help 2`)) { /* do 2 */ }
else if (message.content.startsWith(`${prefix}help 3`)) { /* do 3 */ }
else if (message.content.startsWith(`${prefix}help 4`)) { /* do 4 */ }
else if (message.content.startsWith(`${prefix}help`)) { /* do other */ }
else if (message.content.startsWith(`${prefix}faq`)) { /* do faq */ }
The code above will only match the second case if the first didn't match.
Further explanation:
When comparing partial strings you need to be careful that you're matching the correct thing. Look at this example:
let names = [ "Roberta", "Robert" ]
// case #1 - fails (wrong order)
names.forEach(name => {
let salutation;
if (name.startsWith("Robert"))
salutation = "Mr.";
else if (name.startsWith("Roberta"))
salutation = "Miss";
console.log("1) "+salutation+" "+name);
})
// case #2 - fails (missing else)
names.forEach(name => {
let salutation;
if (name.startsWith("Roberta"))
salutation = "Miss";
if (name.startsWith("Robert"))
salutation = "Mr.";
console.log("2) "+salutation+" "+name);
})
// case #3 - works
names.forEach(name => {
let salutation;
if (name.startsWith("Roberta"))
salutation = "Miss";
else if (name.startsWith("Robert"))
salutation = "Mr.";
console.log("3) "+salutation+" "+name);
})
Case #1 fails because both names match on the first if-statement because both names actually do start with "Robert". But we didn't want it to match "Roberta" because we have a second check for that start of the string. However the code never went into the second if-statement because it already matched on the first one. By reversing the order of checking and putting the check for "Roberta" first we get the right behaviour because it's more specific ('Robert' doesn't start with 'Roberta' but 'Roberta' does start with 'Robert'). So the important part is to order your if-statements to match with the most specific before the more general values.
Case #2 fails because even if the first if-statement matches, the second one can also match. We want to use else if to make sure that if something earlier in the code has already matched that we don't keep checking other cases.
A better way to do this would be to check the page number for your help command:
if(msg.startsWith(prefix)){
let args = msg.slice(1).split(" ");
let command = args.shift(); //shift removes the first element of the array and returns it
if(command === 'help'){
let helpPage = args[0] || "1"; //take the page from the msg if supplied, otherwise default to page 1;
if(helpPage === "1"){ /* send page 1 */ }
else if(helpPage === "2"){ /* send page 2 */ }
// and so on
}
}

How to convert BigQuery Struct Schema string to Javascript object?

I have extracted the schema of my BigQuery table from the "INFORMATION_SCHEMA" table. I get the list of all the columns in the table in a proper Javascript Object format except of the "Struct" and "Array" data types. I need a clean way to convert the "Struct" and "Array" string into a javascript object.
I am working with NodeJS v11.2 I have written a small regex which extracts the following. But it doesn't seem right to split the string and iterate through each word until I get the output. I need a cleaner way to solve this.
let structString = "STRUCT<name STRING, email STRING, time_sec INT64, tz_offset INT64, date STRUCT<seconds INT64, nanos INT64>>";
let _structSchema = structString.match(/STRUCT<([^)]+)>/)[1];
console.log(_structSchema); // name STRING, email STRING, time_sec INT64, tz_offset INT64, date STRUCT<seconds INT64, nanos INT64>
I need to write a recursive function which will parse though the string and give me the output in following manner.
{
"name": "STRING",
"email": "STRING",
"time_sec": "INT64",
"tz_offset": "INT64",
"date": {
"seconds": "INT64",
"nanos": "INT64"
}
}
The function should run irrespective of the depth/hierarchy of the nested structs/arrays.
Using a regex can be good to tokenise the input string, but you'll need more logic to perform the actual parsing.
Here is how you could do it:
function parse(structString) {
let tokenizer = /([a-z_]\w*)|\S|$/gi;
function next(identifier, expected) {
let match = tokenizer.exec(structString);
function error(expected) {
throw `Expected ${expected} but got ${match[0]} at ${match.index}`;
}
match[0] = match[0] || "<EOF>";
if (identifier && !match[1]) error(identifier);
if (expected && !expected.includes(match[0])) error(expected.join(" or "))
return match[0];
}
function getType() {
let fieldType = next("type identifier or STRUCT or ARRAY");
if (fieldType === "STRUCT") {
next(null, ["<"]);
fieldType = {};
do {
fieldType[next("field identifier")] = getType();
} while (next(null, [",", ">"]) === ",");
} else if (fieldType === "ARRAY") {
next(null, ["<"]);
fieldType = [getType()];
next(null, [">"]);
}
return fieldType;
}
let result = getType();
next(null, ["<EOF>"]);
return result;
}
// Sample input & call
let structString = "STRUCT<name STRING, email STRING, time_sec INT64, tz_offset INT64, date STRUCT<seconds INT64, nanos INT64>, phones ARRAY<STRING>>";
let obj = parse(structString);
console.log(obj);
If you can access Google Cloud Console from your environment, consider running something like: bq show --format=pretty project:dataset.table or bq show --format=prettyjson project:dataset.table. You would still need to parse the results for your purposes, but the nesting is already done for you.

How to parse the key and get its value in javascript

I am opening a URL from javascript. I need to look for the term "colour: x" and then retrieve the value x.
request.get("URL", function (error, res, body)
val = body.indexOf('colour') -> works
which means that web page has the string "colour".
Web page looks like this
size: 8 colour: 1
So, Here I need to retrieve the value of the key 'colour'.
To search for a pattern in any general text:
You can use a regular expression if you know how your information is written.
This regular expression should do the job :
/\bcolour:\s+(\d+)/
(the word "colour:" followed by any space, and then by any number of digits (\d+).
It captures the digits, so this will be the value of the first capture group (found[1]) in my example.
body = `size: 8 colour: 1`
let regex = /\bcolour:\s+(\d+)/;
let found = body.match(regex);
console.log(found[1]);
In the case there is no match (i.e., no 'colour: xx' in the page), the found result will be null, so you should of course check for it before, for safety.
body = `size: 8 but unfortunately, no colour here`
let regex = /\bcolour:\s+(\d+)/;
let found = body.match(regex);
//console.log(found[1]); // Uncaught TypeError: Cannot read property '1' of null
// This snippet below is safe to use :
if (found) {
console.log(found[1]);
} else {
console.log('not found');
}

Javascript substring check

I am working with images, they all have their sizes mentioned in their name tag.
http://mysite.com/audio/display%20image/130x130%20jpeg/5755285.jpg
I am getting those is an array of strings. I need to check if the string contains the size
130x130 in it. How can it be done?
var str = 'http://mysite.com/audio/display%20image/130x130%20jpeg/5755285.jpg';
var search = '130x130';
str.indexOf(search);
If it returns anything but -1 the string has been found:
if (str.indexOf(search) > -1) {
// Your image contains 130x130
} else {
// Your image does not contains 130x130
}

Jquery autocomplete, how to search on words instead of string

I have a textbox where i want to have an autocomplete that lets the user search through addresses. The user must be able to type in different words and the autocomplete must search through them to narrow its list.
I've been trying and reading the documentation, but nothing seems to do the trick as it always searches on the whole string instead of the words. Am i missing something?
Example:
When the user enters 'Mathias Antwerp' he must see all the addresses that contain those words. In the example it must show 1 row which is the second one.
<script>
var addresses = [
{ name: "Frederick Dereave Gentstreet 4 Gent" },
{ name: "Mathias Derian Meilaan 9 Antwerp" },
{ name: "Mathias Hors frelaan 5 Kortrijk" }
];
$(document).ready(SetAutoComplete);
function SetAutoComplete() {
$("#testveld").autocomplete(emails,
{
matchContains: "word"
}
);
}
</script>
<input type="text" id="testveld" style='width:300px'/>
I altered the code of matchSubset in jquery.autocomplete.js which enables the behavior i was looking for.
function matchSubset(s, sub) {
var arraySub=sub.split(" ");
if (!options.matchCase)
s = s.toLowerCase();
var i = s.indexOf(sub);
if (options.matchContains == "word"){
i = s.toLowerCase().search("\\b" + sub.toLowerCase());
}
//addition for split words
if (options.matchContains == "splittedword"){
for(itemindex=0;itemindex<arraySub.length;itemindex++){
i = s.toLowerCase().search(arraySub[itemindex].toLowerCase());
if(i==-1){
break;
}
}
}
if (i == -1) return false;
return i == 0 || options.matchContains;
};
AFAIK, you will have to to do some processing on your own to parse the string into words. You can do this using jquery or if you plan to get the addresses from server side then use some server side language.

Categories