Not Understanding How to Capitalizing Text in Angular - javascript

My friend helped me write a custom filter in AngularJS to help me capitalize one of the values in my object for one of my arrays. But didn't have time to explain to me what he did. Was just wondering if anyone can be kind to help me understand this block of code:
.filter('capitalizetext', function() {
return function(name) {
name = ( name === undefined || name === null ) ? '' : name;
return name.toString().toLowerCase().replace( /\b([a-z])/g, function(change) {
return change.toUpperCase();
});
};
})
1st part that I don't understand is:
name = ( name === undefined || name === null ) ? '' : name;
Why did he do this?
2nd part I don't understand is:
return name.toString().toLowerCase().replace( /\b([a-z])/g,
I understand that he is changing the string to all lowercase so that he can eventually convert it to capitalize the string but what is this: ( /\b([a-z])/g
Not really following what he did there.
Please help!

name = ( name === undefined || name === null ) ? '' : name;
This ensures that name is never null or undefined when using it later.
return name.toString().toLowerCase().replace( /\b([a-z])/g, function(change) {
return change.toUpperCase();
});
};
First change everything to lowercase and replace the first character of EVERY word to the uppercase version. \b is a boundary matcher:
E.g. suppose name = "capItalIze me"
Then
name.toString().toLowerCase(); // => name = "capitalize me"
/\b([a-z])/g // means find first letter of every word so will match "c" and "m"
replace( /\b([a-z])/g, function(change) {return change.toUpperCase();});} // change 'c' to 'C' and 'm' to 'M';

In the first part:
name = ( name === undefined || name === null ) ? '' : name;
He checks to see if the string is truthy in his "definition", checking if it is undefined or null (as a null/undefined string could raise errors), else if it is, he sets it to an empty string to avoid errors.
The second part he uses a regex expression to modify the string to the filter specification. You can read about regex expression here. I am not well versed in regex, but I think you are on the right track when he converts all characters to lowercase, check the comment made above for the regex explanation, however, if this is the case, he could just do this...
string = string.toLowerCase()
string = string.substr(0, 1).toUpperCase() + string.substr(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 :'));

Validate input with regular expression for universal alphabets in javascript

I have a form validator by AntonLapshin where I'm trying to validate a non-empty input field which can only take alphabets, space, - and '. The alphabets can be a-z, A-Z and europian letters æÆøØåÅöÖéÉèÈüÜ, etc. See this for more details.
Here is what I am doing:
method : function(input) {
return input.value !== ''
&& input.value === /^[a-zA-Z'\- \u00c0-\u017e]+$/
}
Here, it should match: Åløæ-Bond Mc'Cool
But fail: 123-Bond Mc'C#o!
When I run ^[a-zA-Z'\- \u00c0-\u017e]+$ in regex tester, It works absolutely fine, but in my script, it is not validating and throws an invalid input error.
What am I doing wrong?
I prefer to use RegExp. You also need to do return pattern.test(input)
This will work :)
var test1 = "Åløæ-Bond Mc'Cool";
var test2 = "123-Bond Mc'C#o!";
var pattern = new RegExp(/^[a-zA-Z'\- \u00c0-\u017e]+$/);
function regextest(input) {
return input !== '' && pattern.test(input)
}
console.log(regextest(test1))
console.log(regextest(test2))
modify your function to test with regex
var pattern = /^[a-zA-Z'\- \u00c0-\u017e]+$/
var method = function(input) {
return input !== '' &&
pattern.test(input)
}
//your sample strings
console.log(method("Åløæ-Bond Mc'Cool"))
console.log(method("123 - Bond Mc 'C#o!"))
I figured out a simpler solution for my question:
method : function(input) {
return input.value !== '' && /^[a-zA-Z'\- \u00c0-\u017e]+$/.test(input.value)
}
The problem was, after the && operator, I was checking for the input value (that’s wrong in regex check) instead of Boolean value.
This solution works perfectly and creates no confusion.

RegExp filter in JavaScript (Angular.js)

I want to custom filter in Angular.js.
In case an object has name == null, and I insert "u" to filter-> it returns obj, which name == null because re.test(null)=true, but others characters are returning false. Can you tell me why? How can I prevent this case?
You need to check if obj.name is also defined before testing it with regexp:
$scope.searchFilter = function(obj) {
var re = new RegExp($scope.searchText, 'i');
return !$scope.searchText || (obj.name && re.test(obj.name)) || re.test(obj.age.toString());
};
Otherwise, null casted to String type yields "null" and it's matched of course.
Demo: http://jsfiddle.net/26fZb/232/

C# String.IsNullOrEmpty Javascript equivalent

I want to try to do string call equivalent to the C# String.IsNullOrEmpty(string) in javascript. I looked online assuming that there was a simple call to make, but I could not find one.
For now I am using a if(string === "" || string === null) statement to cover it, but I would rather use a predefined method (I keep getting some instances that slip by for some reason)
What is the closest javascript (or jquery if then have one) call that would be equal?
You're overthinking. Null and empty string are both falsey values in JavaScript.
if(!theString) {
alert("the string is null or empty");
}
Falsey:
false
null
undefined
The empty string ''
The number 0
The number NaN
If, for whatever reason, you wanted to test only null and empty, you could do:
function isNullOrEmpty( s )
{
return ( s == null || s === "" );
}
Note: This will also catch undefined as #Raynos mentioned in the comments.
if (!string) {
// is emtpy
}
What is the best way to test for an empty string with jquery-out-of-the-box?
If you know that string is not numeric, this will work:
if (!string) {
.
.
.
You can create one Utility method which can be reused in many places such as:
function isNullOrEmpty(str){
var returnValue = false;
if ( !str
|| str == null
|| str === 'null'
|| str === ''
|| str === '{}'
|| str === 'undefined'
|| str.length === 0 ) {
returnValue = true;
}
return returnValue;
}
you can just do
if(!string)
{
//...
}
This will check string for undefined, null, and empty string.
To be clear, if(!theString){//...} where theString is an undeclared variable will throw an undefined error, not find it true. On the other hand if you have: if(!window.theString){//...} or var theString; if(!theString){//...} it will work as expected. In the case where a variable may not be declared (as opposed to being a property or simply not set), you need to use: if(typeof theString === 'undefined'){//...}
My preference is to create a prototype function that wraps it up for you.
Since the answer that is marked as correct contains a small error, here is my best try at coming up with a solution. I have two options, one that takes a string, the other takes a string or a number, since I assume many people are mixing strings and numbers in javascript.
Steps:
-If the object is null it is a null or empty string.
-If the type is not string (or number) it's string value is null or empty. NOTE: we might throw an exception here as well, depending on preferences.
-If the trimmed string value has a length that is small than 1 it is null or empty.
var stringIsNullOrEmpty = function(theString)
{
return theString == null || typeof theString != "string" || theString.trim().length < 1;
}
var stringableIsNullOrEmpty = function(theString)
{
if(theString == null) return true;
var type = typeof theString;
if(type != "string" && type != "number") return true;
return theString.toString().trim().length < 1;
}
you can say it by logic
Let say you have a variable name a strVal, to check if is null or empty
if (typeof (strVal) == 'string' && strVal.length > 0)
{
// is has a value and it is not null :)
}
else
{
//it is null or empty :(
}

Count number of matches of a regex in Javascript

I wanted to write a regex to count the number of spaces/tabs/newline in a chunk of text. So I naively wrote the following:-
numSpaces : function(text) {
return text.match(/\s/).length;
}
For some unknown reasons it always returns 1. What is the problem with the above statement? I have since solved the problem with the following:-
numSpaces : function(text) {
return (text.split(/\s/).length -1);
}
tl;dr: Generic Pattern Counter
// THIS IS WHAT YOU NEED
const count = (str) => {
const re = /YOUR_PATTERN_HERE/g
return ((str || '').match(re) || []).length
}
For those that arrived here looking for a generic way to count the number of occurrences of a regex pattern in a string, and don't want it to fail if there are zero occurrences, this code is what you need. Here's a demonstration:
/*
* Example
*/
const count = (str) => {
const re = /[a-z]{3}/g
return ((str || '').match(re) || []).length
}
const str1 = 'abc, def, ghi'
const str2 = 'ABC, DEF, GHI'
console.log(`'${str1}' has ${count(str1)} occurrences of pattern '/[a-z]{3}/g'`)
console.log(`'${str2}' has ${count(str2)} occurrences of pattern '/[a-z]{3}/g'`)
Original Answer
The problem with your initial code is that you are missing the global identifier:
>>> 'hi there how are you'.match(/\s/g).length;
4
Without the g part of the regex it will only match the first occurrence and stop there.
Also note that your regex will count successive spaces twice:
>>> 'hi there'.match(/\s/g).length;
2
If that is not desirable, you could do this:
>>> 'hi there'.match(/\s+/g).length;
1
As mentioned in my earlier answer, you can use RegExp.exec() to iterate over all matches and count each occurrence; the advantage is limited to memory only, because on the whole it's about 20% slower than using String.match().
var re = /\s/g,
count = 0;
while (re.exec(text) !== null) {
++count;
}
return count;
(('a a a').match(/b/g) || []).length; // 0
(('a a a').match(/a/g) || []).length; // 3
Based on https://stackoverflow.com/a/48195124/16777 but fixed to actually work in zero-results case.
Here is a similar solution to #Paolo Bergantino's answer, but with modern operators. I'll explain below.
const matchCount = (str, re) => {
return str?.match(re)?.length ?? 0;
};
// usage
let numSpaces = matchCount(undefined, /\s/g);
console.log(numSpaces); // 0
numSpaces = matchCount("foobarbaz", /\s/g);
console.log(numSpaces); // 0
numSpaces = matchCount("foo bar baz", /\s/g);
console.log(numSpaces); // 2
?. is the optional chaining operator. It allows you to chain calls as deep as you want without having to worry about whether there is an undefined/null along the way. Think of str?.match(re) as
if (str !== undefined && str !== null) {
return str.match(re);
} else {
return undefined;
}
This is slightly different from #Paolo Bergantino's. Theirs is written like this: (str || ''). That means if str is falsy, return ''. 0 is falsy. document.all is falsy. In my opinion, if someone were to pass those into this function as a string, it would probably be because of programmer error. Therefore, I'd rather be informed I'm doing something non-sensible than troubleshoot why I keep on getting a length of 0.
?? is the nullish coalescing operator. Think of it as || but more specific. If the left hand side of || evaluates to falsy, it executes the right-hand side. But ?? only executes if the left-hand side is undefined or null.
Keep in mind, the nullish coalescing operator in ?.length ?? 0 will return the same thing as using ?.length || 0. The difference is, if length returns 0, it won't execute the right-hand side... but the result is going to be 0 whether you use || or ??.
Honestly, in this situation I would probably change it to || because more JavaScript developers are familiar with that operator. Maybe someone could enlighten me on benefits of ?? vs || in this situation, if any exist.
Lastly, I changed the signature so the function can be used for any regex.
Oh, and here is a typescript version:
const matchCount = (str: string, re: RegExp) => {
return str?.match(re)?.length ?? 0;
};
('my string'.match(/\s/g) || []).length;
This is certainly something that has a lot of traps. I was working with Paolo Bergantino's answer, and realising that even that has some limitations. I found working with string representations of dates a good place to quickly find some of the main problems. Start with an input string like this:
'12-2-2019 5:1:48.670'
and set up Paolo's function like this:
function count(re, str) {
if (typeof re !== "string") {
return 0;
}
re = (re === '.') ? ('\\' + re) : re;
var cre = new RegExp(re, 'g');
return ((str || '').match(cre) || []).length;
}
I wanted the regular expression to be passed in, so that the function is more reusable, secondly, I wanted the parameter to be a string, so that the client doesn't have to make the regex, but simply match on the string, like a standard string utility class method.
Now, here you can see that I'm dealing with issues with the input. With the following:
if (typeof re !== "string") {
return 0;
}
I am ensuring that the input isn't anything like the literal 0, false, undefined, or null, none of which are strings. Since these literals are not in the input string, there should be no matches, but it should match '0', which is a string.
With the following:
re = (re === '.') ? ('\\' + re) : re;
I am dealing with the fact that the RegExp constructor will (I think, wrongly) interpret the string '.' as the all character matcher \.\
Finally, because I am using the RegExp constructor, I need to give it the global 'g' flag so that it counts all matches, not just the first one, similar to the suggestions in other posts.
I realise that this is an extremely late answer, but it might be helpful to someone stumbling along here. BTW here's the TypeScript version:
function count(re: string, str: string): number {
if (typeof re !== 'string') {
return 0;
}
re = (re === '.') ? ('\\' + re) : re;
const cre = new RegExp(re, 'g');
return ((str || '').match(cre) || []).length;
}
Using modern syntax avoids the need to create a dummy array to count length 0
const countMatches = (exp, str) => str.match(exp)?.length ?? 0;
Must pass exp as RegExp and str as String.
how about like this
function isint(str){
if(str.match(/\d/g).length==str.length){
return true;
}
else {
return false
}
}

Categories

Resources