Check occurrence of element in string with Regex? - javascript

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 :'));

Related

Way to test empty length property for null and return a string?

I am working through a challenge and trying to set it up so in the event that you pass a string you can determine if there are between 2 and 4 of the letter argument in that string.
My testing of the function worked, however if the matched array is 0 length (in the event there are no matching letters in said string) there is no way to measure the length. I get the error : TypeError: Cannot read property 'length' of null
I tried using a conditional that would return a string if the length was null. Didn't work, I'm not sure if there is a way to funnel this error into a conditional. Any ideas?
TLDR: Is there a way catch to TypeError: Cannot read property 'length' of null before it throws an error?
function countLetters(string, letter) {
let regex = new RegExp(letter, 'g');
let matched = string.match(regex);
if (matched.length == null) {
return "There are no matching characters.";
} else {
let totalLetters = matched.length;
return (totalLetters >= 2 && totalLetters <= 4)? true : false;
}
}
countLetters('Letter', 'e');
true
countLetters('Letter', 'r');
false
countLetters('Letter', 'z');
//TypeError: Cannot read property 'length' of null
If(matched == null || matched.length != 0)
You can try let matched = string.match(regex) || [];
matched.length == null will always be false, so try matched.length === 0
two changes required to make it work as you need:
handle null when no match is found
check for length appropriately
corrected code below:
function countLetters(string, letter) {
let regex = new RegExp(letter, 'g');
let matched = string.match(regex) || [];
if (matched.length == 0) {
return "There are no matching characters.";
} else {
let totalLetters = matched.length;
return (totalLetters >= 2 && totalLetters <= 4)? true : false;
}
}
i would strongly advise that you name your method appropriately. it isn't aligned with the return value or it's type. also, you return either string or a boolean value. one should refrain from that. return values of the same type irrespective of whether a match is found or otherwise.

Check if entries are seperated by comma

I have several strings that contain entries separated by a comma, for example:
('ENTRY1', 'ENTRY2','ENTRY3')
As you can see, each entry is separated by a comma, either with or without a following blank.
How can I check with JavaScript if between each entry there is always a comma (with or without a blank).
The string can contain 0 to n entries.
Requirement: A script should return true or false based on the following example:
('ENTRY1', 'ENTRY2','ENTRY3') // return false
('ENTRY1' 'ENTRY2''ENTRY3') // return true
('ENTRY1','ENTRY2''ENTRY3') // return true
false = correct entry
true = false entry
From your example:
('ENTRY1', 'ENTRY2','ENTRY3') // return false
('ENTRY1' 'ENTRY2''ENTRY3') // return true
('ENTRY1','ENTRY2''ENTRY3') // return true
Since entry is enclosed within single quote (' '), you can do
function validate(entries) {
if (entries.replace(/ /g, '').indexOf("''") > -1) {
return true;
} else {
return false;
}
}
//Test case
var entries1 = "('ENTRY1', 'ENTRY2','ENTRY3')";
var entries2 = "('ENTRY1' 'ENTRY2''ENTRY3')";
var entries3 = "('ENTRY1','ENTRY2''ENTRY3')";
document.write(validate(entries1)+","+validate(entries2)+","+validate(entries3));
You could use split like this:
var splitArray = someString.split(',');
for explicitly stating its separated by a ,
If I understand this correctly,
you can use regex for this to make sure there's always a comma between two items if your string is exactly as you mention above
var str = "('ENTRY1', 'ENTRY2','ENTRY3')";
str = str.match(/'([^'])+'/g).join(',');
since you updated your code you can use this code to achieve following
('ENTRY1', 'ENTRY2','ENTRY3') // return false
('ENTRY1' 'ENTRY2''ENTRY3') // return true
('ENTRY1','ENTRY2''ENTRY3') // return true
false = correct entry true = false entry
function isNotOK(str){
var match = str.match(/'[^,i]+'/g);
var len = str.match(/'([^'])+'/g)
if(match && len && match.length === len.length){
return false;
}
return true;
}
var str1 = "('ENTRY1', 'ENTRY2','ENTRY3')";
var str2 = "('ENTRY1' 'ENTRY2''ENTRY3')";
document.write(isNotOK(str1) + ' , ' + isNotOK(str2));

Use javascript to return true if a string contains an exact match

I've been using the .indexOf('') > -1 in order to check whether there's a match in a string. The problem that I'm having is that when I'm performing the match on multiple strings, I get a match on the string for both EIFT and EI (since EIFT contains EI), and so the function returns true for both sentences. What I need is a way for this to only return true for function eIft if the string is "EIFT", but not for EI.
My current code is as follows, and I've been trying to think of ways around this but haven't had any success yet.
function eI(mystring){
return mystring.indexOf("EI") > -1
}
function eIft(mystring){
return mystring.indexOf("EIFT") > -1
}
Thanks!
You can use ===; that will do an exact match of strings. Use indexOf only if you're checking whether the string contains another string.
function eI (mystring) {
return mystring === "EI";
}
function eIFt(mystring) {
return mystring === "EIFT";
}
If you are checking inside a string for you values (e.g. heleilo), then you need to confirm your positive results for the 'EI' check:
function eI(mystrng) {
return mystring.indexOf("EI") != -1 && !eIFt(mystring);
}
This would only work provided they don't both exist in different occurences (e.g. heleileifto). In this case, you have to check the immediate following characters:
function eI(mystring) {
var pos = mystring.indexOf("EI");
if (pos != -1) { // found
var char1 = mystring[pos + 2];
var char2 = mystring[pos + 3];
return char1 !== 'F' && char2 !== 'T';
}
}
OR
function eI(mystring) {
var pos = mystring.indexOf("EI");
if (pos != -1) { // found
return pos != eIFt(mystring); // they won't have the same index
}
}

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
}
}

Check if string contains only digits

I want to check if a string contains only digits. I used this:
var isANumber = isNaN(theValue) === false;
if (isANumber){
..
}
But realized that it also allows + and -. Basically, I want to make sure an input contains ONLY digits and no other characters. Since +100 and -5 are both numbers, isNaN() is not the right way to go.
Perhaps a regexp is what I need? Any tips?
how about
let isnum = /^\d+$/.test(val);
string.match(/^[0-9]+$/) != null;
String.prototype.isNumber = function(){return /^\d+$/.test(this);}
console.log("123123".isNumber()); // outputs true
console.log("+12".isNumber()); // outputs false
If you want to even support for float values (Dot separated values) then you can use this expression :
var isNumber = /^\d+\.\d+$/.test(value);
Here's another interesting, readable way to check if a string contains only digits.
This method works by splitting the string into an array using the spread operator, and then uses the every() method to test whether all elements (characters) in the array are included in the string of digits '0123456789':
const digits_only = string => [...string].every(c => '0123456789'.includes(c));
console.log(digits_only('123')); // true
console.log(digits_only('+123')); // false
console.log(digits_only('-123')); // false
console.log(digits_only('123.')); // false
console.log(digits_only('.123')); // false
console.log(digits_only('123.0')); // false
console.log(digits_only('0.123')); // false
console.log(digits_only('Hello, world!')); // false
Here is a solution without using regular expressions:
function onlyDigits(s) {
for (let i = s.length - 1; i >= 0; i--) {
const d = s.charCodeAt(i);
if (d < 48 || d > 57) return false
}
return true
}
where 48 and 57 are the char codes for "0" and "9", respectively.
This is what you want
function isANumber(str){
return !/\D/.test(str);
}
in case you need integer and float at same validation
/^\d+\.\d+$|^\d+$/.test(val)
function isNumeric(x) {
return parseFloat(x).toString() === x.toString();
}
Though this will return false on strings with leading or trailing zeroes.
Well, you can use the following regex:
^\d+$
if you want to include float values also you can use the following code
theValue=$('#balanceinput').val();
var isnum1 = /^\d*\.?\d+$/.test(theValue);
var isnum2 = /^\d*\.?\d+$/.test(theValue.split("").reverse().join(""));
alert(isnum1+' '+isnum2);
this will test for only digits and digits separated with '.' the first test will cover values such as 0.1 and 0 but also .1 ,
it will not allow 0. so the solution that I propose is to reverse theValue so .1 will be 1. then the same regular expression will not allow it .
example :
theValue=3.4; //isnum1=true , isnum2=true
theValue=.4; //isnum1=true , isnum2=false
theValue=3.; //isnum1=flase , isnum2=true
Here's a Solution without using regex
const isdigit=(value)=>{
const val=Number(value)?true:false
console.log(val);
return val
}
isdigit("10")//true
isdigit("any String")//false
If you use jQuery:
$.isNumeric('1234'); // true
$.isNumeric('1ab4'); // false
If you want to leave room for . you can try the below regex.
/[^0-9.]/g
c="123".match(/\D/) == null #true
c="a12".match(/\D/) == null #false
If a string contains only digits it will return null

Categories

Resources