I am a new to JavaScript. I have tried to use regular expression in ifcondition.
Here is my code:
var location1 = 3;
var location2 = 4;
var location3 = 5;
var guess;
var hits = 0;
var guesses = 0;
var string = "";
var reg = /[0-6]/i;
var isSunk = false;
while (isSunk == false) {
guess = prompt("Ready, aim, fire! (enter a number 0-6): ");
if (guess != reg || guess ==string) {
alert("Please enter a valid cell number!");
} else {
guesses = guesses + 1;
if (guess == location1 || guess == location2 || guess == location3) {
hits = hits + 1;
alert("HIT!");
if (hits == 3) {
isSunk = true;
alert("You sank my battleship!");
}
} else {
alert("MISS!");
}
}
}
var stats = "You took " + guesses + " guesses to sink the battleship, " + "which means your shooting accuracy was " + (3 / guesses);
alert(stats);`
My problem is in this if (guess != reg || guess ==string) condition. It didn't work as I expected. I would like that function prompt allows only 0,1,2,3,4,5,6 numbers without any words and spaces. But in fact If I enter one of needed number (1 for example) it won't allow to execute further actions. I read a lot through stackoverflow about regular expression in Javascript (Convert the Regular expression, Regular expression, Basic regular expression) and more but I could not find the answer to my problem.
So the question is:
How to set proper regular expression in if condition in JavaScript if it has already declared as variable?
To test whether a string matches a regular expression you can't just compare them using the standard comparison operators. Something that should work is
if (reg.test(guess)) {
....
}
Also the regular expression [0-6]i also matches the string "hello1, since there is a one in it. What you want is probably something like ^[0-6]$. The test for the empty string is also unnecessary, by the way, since "" does not match that expression.
To explain: The ^ and the $ match the beginning and the end of the string, respectively. Framing a regular expression with these symbols essentially says that the whole string, not only a substring, has to match the expression.
Regular expression are not the right tool here.
guess = prompt("Ready, aim, fire! (enter a number 0-6): ");
guess = +guess; // Convert *guess* to number, sets to NaN if not numeric
if (guess >= 0 && guess <= 6) { // check if number is in range (NaN will fail)
....
Related
I have created a JS fiddle https://jsfiddle.net/95r110s9/#&togetherjs=Emdw6ORNpc
HTML
<input id="landlordstreetaddress2" class="landlordinputs" onfocusout="validateinputentries()" />
JS
validateinputentries(){
landlordstreetaddress2 = document.getElementById('landlordstreetaddress2').value;
goodcharacters = "/^[a-zA-Z0-9#.,;:'\s]+$/gi";
for (var i = 0; i < landlordstreetaddress2.length; i++){
if (goodcharacters.indexOf(landlordstreetaddress2.charAt(i)) != -1){
console.log('Character is valid');
}
}
}
Its pulling the value from an input and running an indexOf regex expression with A-Z a-z and 0-9 with a few additional characters as well.
The problem is that it works with the entry of BCDEFG...etc and 12345...etc, but when I type "A" or "Z" or "0" or "1", it returns incorrectly.
I need it to return the same with 0123456789, ABCDEF...XYZ and abcdef...xyz
I should point out that the below does work as intended:
var badcharacters = "*|,\":<>[]`\';#?=+/\\";
badcharacter = false;
//firstname
for (var i = 0; i < landlordfirstname.value.length; i++){
if (badcharacters.indexOf(landlordfirstname.value.charAt(i)) != -1){
badcharacter = true;
break;
}
if(landlordfirstname.value.charAt(0) == " "){
badcharacter = true;
break;
}
}
String.prototype.indexOf()
The indexOf() method returns the index within the calling String object of the first occurrence of the specified value, starting the search at fromIndex. Returns -1 if the value is not found.
So, you're trying to search this value "/^[a-zA-Z0-9#.,;:'\s]+$/gi" which "never" will be found in the entered string.
You actually want to test that regexp against the entered value.
/^[a-zA-Z0-9#.,;:'\s]+$/gi.test(landlordstreetaddress2)
function validateinputentries() {
var landlordstreetaddress2 = document.getElementById('landlordstreetaddress2').value;
if (/^[a-zA-Z0-9#.,;:'\s]+$/gi.test(landlordstreetaddress2)) {
console.log('Characters are valid');
} else {
console.log('Characters are invalid');
}
}
<input id="landlordstreetaddress2" class="landlordinputs" onfocusout="validateinputentries()" />
You're trying to combine two different methods of testing a string -- one way is with a regex; the other way is by checking each character against a list of allowed characters. What you've wound up with is checking each character against a list of what would have been a regex, if you hadn't declared it as a string.
Those methods conflict with each other; you need to pick one or the other.
Check each character:
This is closest to what you were attempting. You can't use character ranges here (like a-zA-Z) as you would in a regex; you have to spell out each allowed character individually:
var validateinputentries = function() {
var address = document.getElementById('landlordstreetaddress2').value;
var goodcharacters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789#.,;:' ";
var badcharactersfound = false;
for (var i = 0; i < address.length; i++) {
if (goodcharacters.indexOf(address.charAt(i)) == -1) {
badcharactersfound = true;
console.log("not allowed: ", address.charAt(i));
}
}
if (badcharactersfound) {
// Show validation error here
}
}
<input id="landlordstreetaddress2" class="landlordinputs" onfocusout="validateinputentries()" />
Regular Expressions
The regex version is much simpler, because the regular expression is doing most of the work. You don't need to step through the string, just test the whole string against the regex and see what comes out. In this case you're looking to see if the input contains any characters that aren't allowed, so you want to use the character exception rule: [^abc] will match any character that is not a, b, or c. You don't want to anchor the match to the beginning or the end of the string, as you were doing with the initial ^ and the trailing $; and you can leave out the + because you don't care if there are sequential bad characters, you just care if they exist at all.
var validateinputentries = function() {
var address = document.getElementById('landlordstreetaddress2').value;
var regex = new RegExp("[^a-zA-Z0-9#.,;:'\\s]","g")
var badcharactersfound = address.match(regex);
// or the above two lines could also have been written like this:
// var bad = address.match(/[^a-zA-Z0-9#.,;:'\s]/g)
// In either case the "g" operator could be omitted; then it would only return the first bad character.
if (badcharactersfound) {
console.log("Not allowed: ", badcharactersfound);
}
}
<input id="landlordstreetaddress2" class="landlordinputs" onfocusout="validateinputentries()" />
I am trying to restrict the user somewhat regarding the username they can use, based on length and context.
Here, I am trying to make my username label red when a forbidden word is found when the user leaves the current textbox.
Although the code looks just fine to me, it seems like it completely ignores the forbidden words and makes the label green anyway if the other criteria a met. What is wrong with my code?
var username = document.forms.LogInForm.username;
username.onblur = function() {
var forbiddenWords = ["fff, dddd, aaa, rrrr, oooo"];
var regex;
var username_value = this.value.split('');
for (var a = 0; a < forbiddenWords.length; a++) {
regex = new RegExp('\\b' + forbiddenWords[a] + '\\b');
if (username_value[username_value.length - 1] === "-" || username_value[username_value.length - 1] === "_") {
console.log('Username cannot end in dash (-) or underscore (_). We removed it for you!');
this.value = this.value.slice(0, -1);
}
else if (this.value.length < 4) {
console.log('Username cannot be less than 4 characters');
document.getElementById('username_label').style.color = "red";
}
else if (username.value.search(regex) >= 0) {
console.log('Username contains swearing word. Please, remove it');
document.getElementById('username_label').style.color = "red";
}
else {
document.getElementById('username_label').style.color = "green";
}
}
};
var forbiddenWords = ["fff, dddd, aaa, rrrr, oooo"];
is most likely a mistake and should read
var forbiddenWords = ["fff", "dddd", "aaa", "rrrr", "oooo"];
You want an array of separate strings, not a one element array containing string which has some commas and spaces as content.
I probably wouldn't use \b. If you use \b the user could just type a swear word then add any character and the regex will not find anything.
Also, if the last forbidden word is not found validation color shows as passed because of your else statement. You should have a separate loop for forbidden words only, and mark a value as valid or invalid and display colors based on that.
Trying to validate if the user has entered a name starting with a letter, is at least 8 characters long, and has at least one number in it. See the code below:-
The first two conditions I have been able to make work, its validating whether or not there's a number within. I have tried to run a function all by itself with just the number validation in it but I cant seem to get it to work. this is my latest attempt to make it work, any help would be greatly appreciated, keep in mind I am a first year student :)
function nameVerify() {
var char1;
var char2;
var index;
var NL = "\n";
var valid = false;
char1 = useNam.substr(0, 1);
char1 = char1.toUpperCase();
char2 = useNam.substr(1);
for (index = 1; index <=useNam.length; index++){
while (!valid) {
if ((char1 <"A" || char1 >"Z") || (useNam.length <8) && (char2 >=0 || char2 <=9)){
alert("alert 1");
useNam = prompt("prompt 2");
char1 = useNam.substr(0, 1);
char1 = char1.toUpperCase();
char2 = useNam.substr(1);
}
else {
valid = true;
alert("Congragulations, you entered it correctly");
}
}
}}
var useNam;
useNam = prompt("prompt 1");
result = nameVerify(useNam);
/**
* #param {string} str name to test
* #return {boolean} true if str is valid
*/
function isValidName(str) {
return /^[a-zA-Z][a-zA-Z0-9]{7,}$/.test(str) && /\d/.test(str)
}
/^[a-zA-Z][a-zA-Z0-9]{7,}$/ tests that it starts with a letter, is at least 8 characters long, and all characters are letters or numbers. /\d/ tests that it contains at least 1 number. See MDN's RegExp documentation for reference in particular about the special characters and the x{n,} syntax described there. If you allow underscores too then you could use /^[a-zA-Z]\w{7,}$/ for the first test.
Try this
valid = myString.match(/\d/).length > 0
This is a regex and will return the first number it matches or an empty array otherwise
I have an infix expression: ((attribute1*attribute2)/attribute3+attribute4)
It may vary according to the user input. I want to check whether the expression is valid.
Valid example: ((attribute1*attribute2)/attribute3+attribute4)
Invalid example: (attrribute1*attribute2+*(attribute3)
The second one has no closing parenthesis; also the * operator is not needed. How can I perform this sort of validation in javascript?
Now this is my regex:
/ *\+? *\-? *[a-zA-Z0-9]+ *( *[\+\-\*\/\=\<\>\!\&\|\%] *\+? *\-? *[a-zA-Z0-9]+ *)*/
I need a regex for comparison operators like <= , >= , != , == etc. How can I implement this?
You could try something like this:
function validateInfix(infix) {
var balance = 0;
// remove white spaces to simplify regex
infix = infix.replace(/\s/g, '');
// if it has empty parenthesis then is not valid
if (/\(\)/.test(infix)) {
return false;
}
// valid values: integers and identifiers
var value = '(\\d+|[a-zA-Z_]\\w*)';
// the unary '+' and '-'
var unaryOper = '[\\+\\-]?';
// the arithmetic operators
var arithOper = '[\\+\\-\\*\\/]';
// the comparison operators
var compOper = '(\\<\\=?|\\>\\=?|\\=\\=|\\!\\=)';
// if it has more than one comparison operator then is not valid
if (infix.match(new RegExp(compOper, 'g')).length > 1) {
return false;
}
// the combined final regex: /[\+\-]?(\d+|[a-zA-Z_]\w*)(([\+\-\*\/]|(\<\=?|\>\=?|\=\=|\!\=))[\+\-]?(\d+|[a-zA-Z_]\w*))*/
var regex = new RegExp(unaryOper + value + '((' + arithOper + '|' + compOper + ')' + unaryOper + value + ')*');
// validate parenthesis balance
for (var i = 0; i < infix.length; i++) {
if (infix[i] == '(') {
balance++;
}
else if (infix[i] == ')') {
balance--;
}
if (balance < 0) {
return false;
}
}
if (balance > 0) {
return false;
}
// remove all the parenthesis
infix = infix.replace(/[\(\)]/g, '');
return regex.test(infix);
}
The idea is to check first the parenthesis balance, then remove them all given that we only want to validate and not evaluate, and then match the remaining expression to a regex (which may not be perfect, I'm not a regex expert). And... just in case: infix argument must be a string.
Edit
I noticed a couple of details and changed the code a bit:
Added the operators you needed the regex to match too.
Removed white spaces to get rid of regex junk.
Checked if the expression had empty parenthesis.
Checked if the expression had more than one comparison operators.
Changed this \+?\-? by this [\+\-]?.
Changed string match method by regex test method where possible.
Changed this [a-zA-Z0-9] by this (\d+|[a-zA-Z_]\w*) since the first one matches wrong identifiers like 53abc.
For better understanding and clarity, extracted pieces of regex into separate variables and built the final one from these.
Hope this is ok for you now :)
I am trying to write a function that decryptes an encrypted message that has uppercase letters (showing its a new word) and lower case characters (which is the word itself). The function needs to search through the encrypted message for all the uppercase letters and then returns the uppercase character along with lower case that follows it. I have been given a function to call on within the decrypt function:
function isUpperCase(aCharacter)
{
return (aCharacter >= 'A') && (aCharacter <= 'Z');
}
I was thinking that I would search through the word for all the uppercase characters first and assign that as a new string. I could then do while loop that will pick up each of the letters in the new string and then search for the lower case characters that are next to it in the old string.
However, I am completely stuck at the first part - I cant even work out the structured English.
The code is:
encryptMessage is a string containing uppercase and lowercase characters
indexCharacter is used at a later date for another function
upperAlphabet - alphabet of uppercase characters - used later
lowerAlphabet - alphabet lowercase characters - used later
The function:
function decryptMessage(encryptMessage, indexCharacter, upperAlphabet, lowerAlphabet)
{
var letter
var word = "";
for (var count = 0; count < encryptMessage.length; count = count +1);
{
letter = encryptMessage.charAt(count)
if (isUpperCase(letter));
{
word = word + letter;
}
document.write(word); //this is just to test to see if it returns the uppercase - I would use the return word
}
The above just doesnt seem to work, so I cant even continue with the rest of the code. Can anyone help me identify where i have gone wrong - have I completely gone the wrong direction with this anyway, reading it back I dont think it really makes much sense ?? Its a very basic code, I have only learnt, for, while loops - if and else functions really, i am just soooooo stuck.
thanks in advance for your advice :-)
Issy
I'm not too sure I follow, but you can strip using the replace method and regular expressions
var str = 'MaEfSdsfSsdfsAdfssdGsdfEsdf';
var newmsg = str.replace(/[a-z]/g, '');
var old = str.replace(/[A-Z]/g, '');
In this case, newmsg = 'MESSAGE'.
A simple condition for checking uppercase characters in a string would be...
var str = 'aBcDeFgHiJkLmN';
var sL = str.length;
var i = 0;
for (; i < sL; i++) {
if (str.charAt(i) === str.charAt(i).toUpperCase()) {
console.log('uppercase:',str.charAt(i));
}
}
/*
uppercase: B
uppercase: D
uppercase: F
uppercase: H
uppercase: J
uppercase: L
uppercase: N
*/
EDIT
String input = "ThisIsASecretText";
for(int i = 0; i < input.Length; i++)
{
if(isUpperCase(input.charAt(i))
{
String nextWord = String.Empty;
for(int j = i; j < input.Length && !isUpperCase(input.charAt(j)); j++)
{
nextWord += input.charAt(j);
i++;
}
CallSomeFunctionWithTheNextWord(nextWord);
}
}
The following calls would be made:
CallSomeFunctionWithTheNextWord("This");
CallSomeFunctionWithTheNextWord("Is");
CallSomeFunctionWithTheNextWord("A");
CallSomeFunctionWithTheNextWord("Secret");
CallSomeFunctionWithTheNextWord("Text");
You can do the same thing with much less code using regular expressions, but since you said that you are taking a very basic course on programming, this solution might be more appropriate.
Use Unicode property escapes, in particular the "Lu" General Property Category, which matches uppercase. There are categories for numbers, punctuation, currency, and just about any other category of character you might be interested in.
In the example below, the "u" modifier enables Unicode matching.
"HeLlo WoRld".match(/\p{Lu}/gu) // [ 'H', 'L', 'W', 'R' ]
I would rather use Array.reduce as follows:
say, example sample = 'SampleStringAsFollows';
let capWord = [...sample].reduce((caps,char) => (char.match(/[A-Z]/)) ? caps + char : caps,'');
console.log(capWord); //SSAF
capWord will be a string of CAPITAL CHARACTERS and will also tackle the boundary cases where in the string may contain special characters.
Please Use Below code to get first Capital letter of the sentence :
Demo Code
var str = 'i am a Web developer Student';
var sL = str.length;
var i = 0;
for (; i < sL; i++) {
if (str.charAt(i) != " ") {
if (str.charAt(i) === str.charAt(i).toUpperCase()){
console.log(str.charAt(i));
}
}
}