JavaScript - Search pattern in string - javascript

hello I would like to know what is the best way to search pattern like
AB where A should be any except A and B should only be B ? Exempple : 'ADSDFSDAB' should return false where as 'BBBSDSSDSDNSSS' should return true.
So, for every B in my string, I want to return true if there is no A preceding it.

where A should be any except A...
So that's [^A]
and B should only be B
And that's B.
So:
if (/[^A]B/.test(str))) {
// Yes, it has a match
} else {
// No, it doesn't
}
Live Example:
test("ADSDFSDAB", false);
test("BBBSDSSDSDNSSS", true);
function test(str, expect) {
var result = /[^A]B/.test(str);
var good = !result == !expect;
console.log("'" + str + "': " + result + (good ? " - Pass" : " - FAIL"));
}

From what I understand, you want to match B not followed by A. You can use a patter like:
[^A]B
however, I'd suggest that you search for the existence of the substring AB in your original string and check the result.
originalString.indexOf('AB') !== -1

Related

Check occurrence of element in string with Regex?

I have strings and some of them may contain : or =
I would like to find all cases, where these symbols occurs, but only once(!).
I wrote this code, which works, but would like to solve with Regex expression
function find(stringToCheck: string): string {
return stringToCheck.includes(':') &&
stringToCheck.split(':').length - 1 === 1
? ':'
: stringToCheck.includes('=') && stringToCheck.split('=').length - 1 === 1
? '='
: '';
}
The string is searched for matches with : or = which are then stored as a RegExp match array. The length of this array then matches how many instances of the string were found.
Where the RexExp objects are created the flag "g" is used to find all matches, rather than just the first one.
function find (stringToTest) {
const a = stringToTest.match(new RegExp(":", "g"));
const b = stringToTest.match(new RegExp("=", "g"));
if (a?.length > 1 || b?.length > 1) return true;
return false;
}
console.log(find("hello:world=")); // false
console.log(find("hello world")); // false
console.log(find("hello world====")); // true
Try this:
function find (stringToCheck)
{
return (/^[^:]*:[^:]*$/.test(stringToCheck) && /^[^=]*=?[^=]*$/.test(stringToCheck))||(/^[^:]*:?[^:]*$/.test(stringToCheck) && /^[^=]*=[^=]*$/.test(stringToCheck));
}
console.log(find("iron:man"));
console.log(find("iron=man"));
console.log(find("iron::man"));
console.log(find("iron==man"));
console.log(find("ironman"));
You could use:
^[^:=]*[:=][^:=]*$
function checkString(str){
return /^[^:=]*[:=][^:=]*$/.test(str);
}
console.log(checkString('Neither'));
console.log(checkString('One equal ='));
console.log(checkString('One colon :'));
console.log(checkString('colon equal :='));
console.log(checkString('Multiple = equal ='));
console.log(checkString('Multiple : colon :'));
console.log(checkString('Multiple = both : col=on :'));

Please explain this recursive javascript function

I was in codewars this morning and there is this Kata asking for a function to reverse a string passed as parameter through recursion method.
The best solution listed for this problem was this.
function reverse(str) {
return str.length > 1 ? reverse(str.slice(1)) + str[0] : str;
}
I researched for this all this morning and I still don't know what is happening here:
+ str[0]
Can somebody please clarify this for me?
The essence of the function is the following:
Take the substring from the second character to the last
Apply the reverse function recursively
Take the first character and append it to the end of the result of the recursive call
Return the result
This results in the following logic, the (recursive) function calls indicated by brackets:
(A B C D E)
((B C D E) A)
(((C D E) B) A)
((((D E) C) B) A)
(((((E) D) C) B) A)
str.slice(1) "chops off" the first letter of the string and returns the rest of it. So 'abcd'.slice(1) gives you 'bcd'.
str[0] is the first letter of the string. 'abcd'[0] is 'a'.
So, str.slice(1) + str[0] is taking the first letter of the string and "moving" it to the end: 'abcd' becomes 'bcda'.
This does not address the recursive nature of the solution, but it answers your question about + str[0].
I'll try to rewrite the function in a more "human-readable" way
reverse = str => {
// If there is still string to reverse
if (str.length > 1) {
let firstChar = str[0]
let strWithoutFirstChar = str.slice(1)
// Notice only a part of the string 'comes back' here
// console.log(strWithoutFirstChar) // Might help
return reverse(strWithoutFirstChar) + firstChar
}
// Else return result as is
else {
return str
}
}
This is the same function, but without ternaries and declaring well named variables.
If you uncomment the console.log() line and call:
reverse('help');
The output should be:
elp
lp
p
'pleh'
Hope it helps!
The + operator is a concatenator for string.
You can instead use concat this :
var reverse = str => str.length > 1 ? reverse(str.slice(1)).concat(str[0]) : str;
console.log(reverse("123456789")); // 987654321

Ordinal string compare in JavaScript?

In javascript:
"Id".localeCompare("id")
will report that "id" is bigger. I want to do ordinal (not locale) compare such that "Id" is bigger. This is similar to String.CompareOrdinal in C#. How can I do it?
I support the answers given by Raymond Chen and pst. I will back them up with documentation from my favorite site for answers to JavaScript questions -- The Mozilla Developer Network. As an aside, I would highly recommend this site for any future JavaScript questions you may have.
Now, if you go to the MDN section entitled String, under the section "Comparing strings", you will find this description:
C developers have the strcmp() function for comparing strings. In JavaScript, you just use the less-than and greater-than operators:
var a = "a";
var b = "b";
if (a < b) // true
print(a + " is less than " + b);
else if (a > b)
print(a + " is greater than " + b);
else
print(a + " and " + b + " are equal.");
A similar result can be achieved using the localeCompare method inherited by String instances.
If we were to use the string "Id" for a and "id" for b then we would get the following result:
"Id is less than id"
This is the same result that Yaron got earlier when using the localeCompare method. As noted in MDN, using the less-than and greater-than operators yields similar results as using localeCompare.
Therefore, the answer to Yaron's question is to use the less-than (<) and greater-than (>) operators to do an ordinal comparison of strings in JavaScript.
Since Yaron mentioned the C# method String.CompareOrdinal, I would like to point out that this method produces exactly the same results as the above JavaScript. According to the MSDN C# documentation, the String.CompareOrdinal(String, String) method "Compares two specified String objects by evaluating the numeric values of the corresponding Char objects in each string." So the two String parameters are compared using the numeric (ASCII) values of the individual characters.
If we use the original example by Yaron Naveh in C#, we have:
int result = String.CompareOrdinal("Id", "id");
The value of result is an int that is less than zero, and is probably -32 because the difference between "I" (0x49) and "i" (0x69) is -0x20 = -32. So, lexically "Id" is less than "id", which is the same result we got earlier.
As Raymond noted (and explained) in a comment, an "ordinal" non-locale aware compare is as simple as using the various equality operators on strings (just make sure both operands are strings):
"a" > "b" // false
"b" > "a" // true
To get a little fancy (or don't muck with [[prototype]], the function is the same):
String.prototype.compare = function (a, b) {
return ((a == b ? 0)
? (a > b : 1)
: -1)
}
Then:
"a".compare("b") // -1
Happy coding.
Just a guess: by inverting case on all letters?
function compareOrdinal(ori,des){
for(var index=0;index<ori.length&&index<des.length;index++){
if(des[index].charCodeAt(0)<ori[index].charCodeAt(0)){
return -1;
break;
}
}
if(parseInt(index)===des.length-1){
return 0;
}
return 1;
}
compareOrdinal("idd","id");//output 1
if you need to compare and find difference between two string, please check this:
function findMissingString() {
var str1 = arguments[0];
var str2 = arguments[1];
var i = 0 ;
var j = 0 ;
var text = '' ;
while(i != (str1.length >= str2.length ? str1.length : str2.length )) {
if(str1.charAt(i) == str2.charAt(j)) {
i+=1 ;
j+=1;
} else {
var indexing = (str1.length >= str2.length ? str1.charAt(i) : str2.charAt(j));
text = text + indexing ;
i+=1;
j+=1;
}
}
console.log("From Text = " + text);
}
findMissingString("Hello","Hello world");

Javascript - Ternary Operator with Multiple Statements

Is this valid JavaScript? I saw an example where someone used commas in the ternary operator conditions, and it was marked as an error in my editor, and the example didn't run in Chrome. However, it did run in Firefox. Once I converted all the ternary statements to if/else statements, the app ran on Chrome.
a!==b ? (a=1, b=2) : (a=2, b=1)
Edit:
This is the actual statement in the code:
a!==0?b<0?(h=b/a,e=h-1,f=-2*b+2*a*e,i=-2*b+2*a*h,d=2*h*a-2*b-2*a):(h=b/a,e=h+1,f=2*b-2*a*e,i=2*b-2*a*h,d=-2*h*a+2*b):d=h=e=f=i=0
Yes, it's valid, and it runs fine in Chrome:
var a, b, c;
a = 6;
b = 7;
c = a !== b ? (a = 1, b = 2) : (a = 2, b = 1);
console.log("a = " + a);
console.log("b = " + b);
console.log("c = " + c);
I'm not saying it's a remotely good idea in code humans are meant to read. :-) I expect jamietre is correct in the comments when he/she says it looks like the result of minification.
The comma operator is a binary operator (an operator accepting two operands). It evaluates its left-hand operand (thus causing any side-effects it has, such as assignment), throws that result away, then evalutes its right-hand operand (thus causing its side-effects if any) and takes that result as its result value. If you have multiple comma operators in a row, the overall expression is evaluated in order, left-to-right, with the final result being the value resulting from the right-most operand evaluation.
And of course, you know the conditional operator (a ternary operator — one accepting three operands) is used to pick one of two sub-expressions to evaluate, on the basis of an initial expression.
So that line is very...expressive...what with a total of seven* different expressions inside it.
So in that example, the result of the overall expression is 2 if a !== b initially, or 1 if a === b initially, with the side-effects of setting a and b.
It's the side effects that make it, in my view, a questionable choice. And of course, there's no reason to use the comma operator if the left-hand operand doesn't have side effects.
* Yes, seven of 'em packed into that overall ternary:
a !== b
the first comma expression
a = 1
b = 2
the second comma expression
a = 2
b = 1
Re your edit with the actual statement, that one works too:
function test(a) {
var b = 7,
d = 1,
e = 2,
f = 3,
g = 4,
h = 5,
i = 6;
a!==0?b<0?(h=b/a,e=h-1,f=-2*b+2*a*e,i=-2*b+2*a*h,d=2*h*a-2*b-2*a):(h=b/a,e=h+1,f=2*b-2*a*e,i=2*b-2*a*h,d=-2*h*a+2*b):d=h=e=f=i=0;
console.log("a = " + a);
console.log("b = " + b);
console.log("d = " + d);
console.log("e = " + e);
console.log("f = " + f);
console.log("g = " + g);
console.log("h = " + h);
console.log("i = " + i);
}
test(0);
test(1);
.as-console-wrapper {
max-height: 100% !important;
}
But wow, I hope this is minified, because if a person wrote that, they must really have a thing against anyone who's supposed to maintain it later... ;-)
Yes:
a=1;
b=2;
a!==b ? (a=1, b=2) : (a=2, b=1)
console.log(a); // 1
console.log(b); // 2
and:
a=1;
b=2;
a===b ? (a=1, b=2) : (a=2, b=1)
console.log(a); // 2
console.log(b); // 1
As you can analyze, changing the equality operator reacts correctly to our test if you look at the results.
Or you can do this :
b = a!==b ? (a=1,2) : (a=2,1);
Read here about comma operator.
The comma operator evaluates each of its operands (from left to right) and returns the value of the last operand.
Expanding on this topic with ES6 code example. If you're using one side of the TRUE : FALSE argument to iterate thru all cases in one IF, it makes sense to separate the code as if it's a switch | case statement.
Nesting implies that there is branching logic, while it is logically nested, writing nested IF's complicates what we're doing in my example. Like a lawyer over explaining a problem to a jury. IMO, you want to explain the point in it's simplest form. For instance, I find this example the most logical way of expressing nested ifs where the TRUE is executed. The final false is your last else {}
choreDoor is either 0,1 or 2:
choreDoor === 0 ?
(openDoor1 = botDoorPath,
openDoor2 = beachDoorPath,
openDoor3 = spaceDoorPath)
: choreDoor === 1 ?
(openDoor2 = botDoorPath,
openDoor1 = beachDoorPath,
openDoor3 = spaceDoorPath)
: choreDoor === 2 ?
(openDoor3 = botDoorPath,
openDoor1 = beachDoorPath,
openDoor2 = spaceDoorPath)
: false;
If you don't want to use the Comma operator (,) then you can use nested Conditional (ternary) operators instead.
var a = 6;
var b = 7;
var c = (a !== b)? // true
((a = 1 || 1===1)? (b = 2) : null) // will first run a=1, then b=2
: ((a = 0 || 1===1)? (b = 0) : null);
console.log("a = " + a);
console.log("b = " + b);
console.log("c = " + c);

Determine whether a string is "empty"

I need a JavaScript function to tell me whether a string object is empty. By "empty", I mean that it's not all just whitespace characters. I've written this prototype:
String.prototype.isEmpty = function() {
return this.length === 0 || this === " " || this.test(/^\s*$/);
}
Is this alright?
Is there a more-performant version of this out there?
Use
String.prototype.isEmpty = function() {
if (!this.match(/\S/)) {
return ('enter some valid input.Empty space is not allowed');
} else {
return "correct input";
}
}
alert("test 1:"+(" ".isEmpty()));
alert("test 2:"+(" \t ".isEmpty()));
alert("test 3:"+(" \n ".isEmpty()));
alert("test 4:"+("hi".isEmpty()));
Note:
\s will match a whitespace character: space, tab or new line.
\S will match non whitespace character:anything but not a space, tab or new line.
If your string has a single character which is not a space, tab or new line, then it's not empty.
Therefore you just need to search for one character: \S
It looks like you need to use /^\s*$/.test(this) instead of this.test(/^\s*$/). There is no test() method for strings, unless you're using some JavaScript library that implements this method.
The /^\s*$/.test(this) would have been enough, but the first two expressions would short circuit if any one of them evaluates to true, without having to test the regular expression. That should be pretty efficient.
As #Matthew Crumley noted in a comment above, your this === " " expression will always evaluate to false. You could remove this expression, or use == if you would will be expecting a lot of strings with just a single space character:
String.prototype.isEmpty = function() {
return this.length === 0 || this == " " || /^\s*$/.test(this);
}
String.prototype.isEmpty = function() {
return this.length == 0 || /^\s*$/.test(this);
}
There is just a possibility out of 255 (not considering Unicode characters with code greater than 255) that a string with length 1 contains the space character. Considering strings with lenght greater than 1, the possibility get even lower.
Generally, using RegExp.prototype.test for checking for a pattern match without compilation of a return array of matches (String.prototype.match) likely has a better performance. I'd try -- but haven't tested yet -- something like:
function isEmpty() {
var string = arguments[0] ;
var EMPTY_STRING_PATTERN = /^\s*$/ , empty = false ;
if( EMPTY_STRING_PATTERN.exec(string) === true ) empty = true ;
return empty ;
}
On a side note, it is considered bad practice to fiddle with the prototype object of core javascript objects.
from example https://developer.mozilla.org/en/JavaScript/Reference/Global_Objects/String/Trim
var orig=" foo "
document.write(orig.trim()) // foo
document.write(orig.trim().length) // 3
tested on FF 3.6.8, Safari 5.0.1, Google Chrome 5.0.375.127, but produce js error on IE 8
I fiddled with some of the things:
I'm returning the inverse of this.length, for 0 that is true, for everything other number that is false.
I removed the check for " ". I actually haven't seen much, if any cases where a single space was entered, removing the check is IMO faster on average.
And flipped the regex <-> string like the others did.
String.prototype.isEmpty = function() {
return !this.length || /^\s*$/.test(this);
}
Same answer as Daniel Vassallo originally provided, in example form.
String.prototype.isEmpty = function() {
    return /^\s*$/.test(this);
}
document.body.style="background-color:black; color:green;font-size:12pt;font-family: 'Courier New', monospace;font-weight: bold";
String.prototype.isEmpty = function() {
return /^\s*$/.test(this);
}
let test0 = ''.isEmpty();
let test1 = '\xa0'.isEmpty();
let test2 = ' '.isEmpty();
let test3 = '\t'.isEmpty();
let test4 = '\n'.isEmpty();
let test5 = '\n\n'.isEmpty();
let test6 = '\n\t\n'.isEmpty();
let test7 = '\r\n'.isEmpty();
let test8 = '\r\t\n'.isEmpty();
let test9 = '\r\n\t'.isEmpty();
var texts = new Array(
("String.prototype.isEmpty = function() {"),
(" return /^\s*$/.test(this);"),
("}"),
(""),
("let test0 = ''.isEmpty() // " + test1),
("let test1 = ' '.isEmpty() // " + test2) + " (non breaking space)",
("let test2 = ' '.isEmpty() // " + test2),
("let test3 = '\\t'.isEmpty() // " + test3),
("let test4 = '\\n'.isEmpty() // " + test4),
("let test5 = '\\n\\n'.isEmpty() // " + test5),
("let test6 = '\\n\\t\\n'.isEmpty() // " + test6),
("let test7 = '\\r\\n'.isEmpty() // " + test7),
("let test8 = '\\r\\t\\n'.isEmpty() // " + test8),
("let test9 = '\\r\\n\\t'.isEmpty() // " + test9)
);
texts.forEach(text => {
let nobreakchar = '\xa0'
;
document.body.append(document.createTextNode(text.replaceAll(" ",nobreakchar)))
document.body.append(document.createElement("br"))
});
Instead of writing more number of lines let's finish it in 2 lines only.
String.prototype.isEmpty = function () {
return this.length === 0 || this.trim() === ""
}
With trim() you don't need to worry about if the variable is only having space characters and that is how you can avoid those falling in regex

Categories

Resources