Match joined AmPm hours with regex - javascript

I have input string in next format : 12:00am|1:20PM|9:30Pm
I need to have in output array of hours like : [12:00am, 1:20PM, 9:30Pm]
But before I shoudl match it with regex.
I have some regex to match AmPm hours and I tried to add | to match full string
\b((1[0-2]|0?[1-9]):([0-5][0-9])([AaPp][Mm]))([|])?. This regex matches string 12:00am|1:20PM|9:30Pm but also matches string 12:00am|1:20PM}9:30Pm which isn't correct.
Where is my mistake in my regex and how can I return expected array.
Thanks

The \b((1[0-2]|0?[1-9]):([0-5][0-9])([AaPp][Mm]))([|])? does not require | as [|]? matches 1 or 0 occurrences of this char. This regex matches 12:00am|1:20PM}9:30Pm as it finds 12:00am and calls it a day (i.e. returns a valid match).
You need to split the string with | and validate each item against /^(1[0-2]|0?[1-9]):([0-5][0-9])([AaPp][Mm])$/ pattern.
var s = "12:00am|1:20PM|9:30Pm";
var re = /^(1[0-2]|0?[1-9]):[0-5][0-9]([AaPp][Mm])$/;
var items = s.split("|");
if (items.filter(function(x) { return re.test(x); }).length === items.length) {
console.log("VALID => ", items);
} else {
console.log("INVALID!");
}
Note you may use a regex to pre-validate the string, but it is just more cumbersome:
var s = "12:00am|1:20PM|9:30Pm";
var re_block = "(1[0-2]|0?[1-9]):([0-5][0-9])([AaPp][Mm])";
var re = new RegExp("^" + re_block + "(?:\\|" + re_block + ")*$");
var isValid = re.test(s);
console.log(isValid ? s.split("|") : "Invalid!");
The regex will look like /^(1[0-2]|0?[1-9]):([0-5][0-9])([AaPp][Mm])(?:\|(1[0-2]|0?[1-9]):([0-5][0-9])([AaPp][Mm]))*$/ and it will validate a string that starts with the time substring, and then has 0 or more occurrences of time substrings up to the string end. See the pattern demo.

Related

I need help getting the first n characters of a string up to when a number character starts

I'm working with a string where I need to extract the first n characters up to where numbers begin. What would be the best way to do this as sometimes the string starts with a number: 7EUSA8889er898 I would need to extract 7EUSA But other string examples would be SWFX74849948, I would need to extract SWFX from that string.
Not sure how to do this with regex my limited knowledge is blocking me at this point:
^(\w{4}) that just gets me the first four characters but I don't really have a stopping point as sometimes the string could be somelongstring292894830982 which would require me to get somelongstring
Using \w will match a word character which includes characters and digits and an underscore.
You could match an optional digit [0-9]? from the start of the string ^and then match 1+ times A-Za-z
^[0-9]?[A-Za-z]+
Regex demo
const regex = /^[0-9]?[A-Za-z]+/;
[
"7EUSA8889er898",
"somelongstring292894830982",
"SWFX74849948"
].forEach(s => console.log(s.match(regex)[0]));
Can use this regex code:
(^\d+?[a-zA-Z]+)|(^\d+|[a-zA-Z]+)
I try with exmaple and good worked:
1- somelongstring292894830982 -> somelongstring
2- 7sdfsdf5456 -> 7sdfsdf
3- 875werwer54556 -> 875werwer
If you want to create function where the RegExp is parametrized by n parameter, this would be
function getStr(str,n) {
var pattern = "\\d?\\w{0,"+n+"}";
var reg = new RegExp(pattern);
var result = reg.exec(str);
if(result[0]) return result[0].substr(0,n);
}
There are answers to this but here is another way to do it.
var string1 = '7EUSA8889er898';
var string2 = 'SWFX74849948';
var Extract = function (args) {
var C = args.split(''); // Split string in array
var NI = []; // Store indexes of all numbers
// Loop through list -> if char is a number add its index
C.map(function (I) { return /^\d+$/.test(I) === true ? NI.push(C.indexOf(I)) : ''; });
// Get the items between the first and second occurence of a number
return C.slice(NI[0] === 0 ? NI[0] + 1 : 0, NI[1]).join('');
};
console.log(Extract(string1));
console.log(Extract(string2));
Output
EUSA
SWFX7
Since it's hard to tell what you are trying to match, I'd go with a general regex
^\d?\D+(?=\d)

Dynamically split string using regex

I am receiving an Australian phone number from the user as a text input. The string will be 10 characters long and begin with 04. I want to split the string as the user is entering it so it turns out like 0411 111 111.
My current solution is value.toString().replace(/^(04\d{2})(\d{3})(\d{3})$/, $1 $2 $3)
This solution splits the string correctly, but only when the user has entered the entire 10 characters. I want it to start splitting after the first 4 characters have been entered ie 0411 1 etc.
Here is a one liner which will work for your exact use case:
var results = "0411111111".split(/(?=\d{6}$)|(?=\d{3}$)/);
console.log(results);
We may split your string on a regex which targets the point after 4 digits and the point after 7 digits.
Consider something like below that checks the length of the currently input mobile number and then applies a different regex depending on the length:
var mobileInput = document.getElementById('mobile');
mobileInput.addEventListener('keyup', foo);
function foo() {
var unformatted = mobileInput.value;
var pattern, replacer;
if (unformatted.length < 5) {
pattern = /(04\d{2})/;
replacer = '$1 ';
} else if (unformatted.length < 9) {
pattern = /(04\d{2})\s{1}(\d{3})/;
replacer = '$1 $2 ';
} else {
pattern = /^(04\d{2})(\d{3})(\d{3})$/;
replacer = '$1 $2 $3';
}
var formatted = unformatted.replace(pattern, replacer);
mobileInput.value = formatted;
}
<input type="text" id="mobile" />
I have managed to come up with a bit of a solution. It is not exactly what I was aiming for, but it does the job.
value.toString()
.replace(/^(04\d{2})(\d{3})(\d{3})$/, $1 $2 $3)
.replace(/[\s-]+$/, "")
This strips out the white space on each keypress (each time the regex is called) and reformats it.
here is my solution:
remove spaces added by before (to recover phone numbers from being splitted)
try to match input using a regex
combine matches and handle some other situations
code:
document.getElementById("phone").addEventListener("input", function() {
var matches = this.value.replace(/ /g, "").match(/^(04\d{2})(\d{3})?(\d{3})?(\d*?)$/);
this.value = matches && matches.length > 2 ?
matches.slice(1, matches.length - 1).join(" ")
+ (matches[matches.length - 1] || "")
: this.value;
});
<input id="phone" maxlength="12">
I'd probably do something like this:
let phone = document.getElementById('phone');
phone.addEventListener('keyup', evt => {
// get value, removing anything that isn't a number
let text = phone.value.replace(/\D/g, '');
// turn it into an array
text = text.split('');
// create a new array containing each group of digits, separated by spaces
let out = [...text.slice(0, 4), ' ', ...text.slice(4, 7), ' ', ...text.slice(7, 10)];
// turn it back into a string, remove any trailing spaces
phone.value = out.join('').trim();
}, false);
<input id="phone">

JS-regex, How can I make it to one replace() method?

My goal is :
Delete all.
except the numbers , but delete the zeros who before numbers 1 to 9
And I have this regex:
var validValue = inputValue.replace(/[^\d]/g, '').replace(/^0*/g, '');
But I want to make it in a one replace()
So how can I do that ?
You want to remove all leading zeros and all non-digit symbols. It can be done with
/^0+|\D+/g
See the regex demo
The regex matches
^0+ - 1 or more leading digits (those at the beginning of the string)
| - or
\D+ - one or more non-digit symbols
var re = /^0*|\D+/g;
var str = '00567600ffg5566';
var result = str.replace(re, '');
document.body.innerHTML = str + " >>> " + result;

regex to remove number (year only) from string

I know the regex that separates two words as following:
input:
'WonderWorld'
output:
'Wonder World'
"WonderWorld".replace(/([A-Z])/g, ' $1');
Now I am looking to remove number in year format from string, what changes should be done in the above code to get:
input
'WonderWorld 2016'
output
'Wonder World'
You can match the location before an uppercase letter (but excluding the beginning of a line) with \B(?=[A-Z]) and match the trailing spaces if any with 4 digits right before the end (\s*\b\d{4}\b). In a callback, check if the match is not empty, and replace accordingly. If a match is empty, we matched the location before an uppercase letter (=> replace with a space) and if not, we matched the year at the end (=> replace with empty string). The four digit chunks are only matched as whole words due to the \b word boundaries around the \d{4}.
var re = /\B(?=[A-Z])|\s*\d{4}\b/g;
var str = 'WonderWorld 2016';
var result = str.replace(re, function(match) {
return match ? "" : " ";
});
document.body.innerHTML = "<pre>'" + result + "'</pre>";
A similar approach, just a different pattern for matching glued words (might turn out more reliable):
var re = /([a-z])(?=[A-Z])|\s*\b\d{4}\b/g;
var str = 'WonderWorld 2016';
var result = str.replace(re, function(match, group1) {
return group1 ? group1 + " " : "";
});
document.body.innerHTML = "<pre>'" + result + "'</pre>";
Here, ([a-z])(?=[A-Z]) matches and captures into Group 1 a lowercase letter that is followed with an uppercase one, and inside the callback, we check if Group 1 matched (with group1 ?). If it matched, we return the group1 + a space. If not, we matched the year at the end, and remove it.
Try this:
"WonderWorld 2016".replace(/([A-Z])|\b[0-9]{4}\b/g, ' $1')
How about this, a single regex to do what you want:
"WonderWorld 2016".replace(/([A-Z][a-z]+)([A-Z].*)\s.*/g, '$1 $2');
"Wonder World"
get everything apart from digits and spaces.
re-code of #Wiktor Stribiżew's solution:
str can be any "WonderWorld 2016" | "OneTwo 1000 ThreeFour" | "Ruby 1999 IamOnline"
str.replace(/([a-z])(?=[A-Z])|\s*\d{4}\b/g, function(m, g) {
return g ? g + " " : "";
});
import re
remove_year_regex = re.compile(r"[0-9]{4}")
Test regex expression here

return number and word regex javascript

can someone tell me why my code keeps returning null, it used to return a match now its not and i dont know whats wrong. I want it to find a match in the string for 1 hour
var error = "null";
var str = "1 hour "
var strCheck = str.match(/[1]\s[hour]\s/g);
if(String(strCheck) != error) {
alert("works!");
}
Check this..
var error = "null";
var str = "1 hour "
var strCheck = str.match(/1 hour /g);
if(strCheck != error) {
alert("works!");
}
Explanation:
[] is used to match a single character so [hour] is not correct and if you have change in number of hours you can make it like this:
var error = "null";
var str = "1 hour "
var strCheck = str.match(/[0-9][0-9] hour /g);
if(strCheck != error) {
alert("works!");
}
or Simply use \d to find a digit and \d+ to find one or more digit.
For more see this its simple and clear.
The RegEx [1]\s[hour]\s will not work. The character class without quantifiers [] is used to match only a single character from the characters within it. So, [hour] will match one of the character from h, o, u and r. However, you want to match hour as complete string.
To make the regex more dynamic and match even 10 hours following regex can be used.
/\d+\s*hours?\s*/
Code:
var error = "null";
var str = "1 hour "
var strCheck = str.match(/\d+\s*hours?\s*/g);
if (strCheck != null) {
alert("works!");
}
console.log(strCheck);
If you just want to check if the string contain a pattern, use RegExp#test instead of String#match.
/\d+\s*hours?\s*/.test(str)
I don't know what kind of validation you need with that regex, but this can be useful:
\d+\s(hour(s)?)
Explanation:
\d+ One or more digits
\s A blank space
(hour(s)?) a string hour with optional s at the end for plural.
The match() method returns an array with the results or null if no match was found. So I suggest you simply check the result as a boolean instead of compare to "null" string. Then you code could be like this:
var strCheck = str.match(/\d+\s(hour(s)?)/, g);
if (strCheck) {
alert("works!");
}
Some cases here.

Categories