I'm writing an Angular 5 directive that validates an IPv4 input as the user types into it.
Currently it works as expected, however it's pretty verbose:
this.el.nativeElement.value = this.el.nativeElement.value
.replace(/^\D+/, '') // Remove any non-digit from position 0
.replace(/[^\d\.]+/, '') // Remove any non-digit, non dot from string
.replace(/\.{2,}/, '.') // Force sequences of dots into one single dot
.split('.').map(seq => seq.substring(0, 3)) // Limit to {1-3} digits per group
.slice(0, 4) // Limit to 4 groups of digits
.join('.') // Turn back into string and give dots back
How could I replace the split-map-slice-join sequence with another RegExp or string method in JavaScript?
Your request is a bit complicated let say fault tolerant. So given
"asdf1.2.3.aaa...4afd"
you are expected to get: "1.2.3.4".
The fist replace (.replace(/^\D+/, '')) seems to be superfluous because of the second replace. And the whole expression might be
var original = "asdf1.2.3.aaa...4afd";
var formatted = original.replace(/[^\d.]/g, "")
.replace(/^\.*(\d+)\.+(\d+)\.+(\d+)\.+(\d+)[^\d]?.*$/g, "$1.$2.$3.$4");
Note that this will give different result to non IPv4 strings. Like "1.2.3" so you may want to test this code as:
var a = "asdf1.2.3.aaa...4afd";
var a = "asdf2.3.aaa...4.5.6af.7d";
var a = "1.2.3.4";
var a = "1.2.3";
var a = "1.2";
var b = a.replace(/[^\d.]/g, "");
var c = b.replace(/^\.*(\d+)\.+(\d+)\.+(\d+)\.+(\d+)[^\d]?.*$/g, "$1.$2.$3.$4");
console.log(a + " " + b + " " + c);
Related
I'm asking you today for a little problem :
I have to live control capitalization/no capitalization with js on an input text field like this:
1st character of the entire string must be uppercase
1st character of each word (after space or hyphen) is free (lowercase or uppercase allowed)
All the nother characters must be lowercase
Desired Output: Grand-Father is Nice
I'm not a specialist of JS, i'm using split function, here is my code :
$('#name').on('input change',function() {
var arr1 = $(this).val().split(/[- ]/);
var result1 = "";
for (var x=0; x<arr1.length; x++)
result1+=arr1[x].substring(0,1)+arr1[x].substring(1).toLowerCase()+" ";
var res1 = result1.substring(0, result1.length-1);
var _txt = res1.charAt(0).toUpperCase() + res1.slice(1);
$('#name').val(_txt);
});
The script works but I would like to output the real delimiter found in string, even if it's a space " " or hyphen "-". Actually i can show only space. How can i solve it ?
Actual output: Grand Father is Nice
Any help would be appreciated.
Thank you!
User String.replace() with a RegExp and a callback.
If you know what are your delimiters, you can search for all characters that are no the delimiters, and format them:
var input = 'ègrand-Father is NièCe';
var d = '[^\s\-]'; // not space or dash
var result = input.replace(new RegExp('('+ d +')(' + d + '+)', 'g'), function(m, p1, p2, i) {
var end = p2.toLowerCase();
var start = i === 0 ? p1.toUpperCase() : p1;
return start + end;
});
console.log(result);
If the target browsers support it (Chrome does) or you use a transpiler, such as Babel (plugin), you can use Unicode property escapes in regular expressions (\p):
var input = 'ègrand-Father is NièCe';
var result = input.replace(/(\p{L})(\p{L}+)/gu, function(m, p1, p2, i) {
var end = p2.toLowerCase();
var start = i === 0 ? p1.toUpperCase() : p1;
return start + end;
});
console.log(result);
I'm not entirely sure what your aim is, but let's give it a shot.
This is how you can make all non-first letters be lowercase
let sentence = "this is wRoNg SenTEnce."
sentence.split(" ").map(word => word.charAt(0) + word.slice(1).toLowerCase()).join(" ")
This is how you can make first letter capital:
let sentence = "also Wrong sentence"
sentence.charAt(0).toUpperCase()
I am trying to get the regular expression that accepts only characters with specific pattern like two characters separated by comma, but I am not able to get it.
Here i included the acceptable sting
string = ab,ca,ls,gz,tv......
I tried:
/^([a-zA-Z]{2},)|([a-zA-Z]{2})*$/
but it is not working as expected.
Try using /^[a-z]{2}(?:,[a-z]{2})*$/i instead (the | inside your pattern was problematic):
var string = 'ab,ca,ls,gz,tv'
var regex = /^[a-z]{2}(?:,[a-z]{2})*$/i
console.log(regex.test(string)) //=> true
If I'm understanding you correctly, then you're trying to get (capture) the 2 characters, with the condition that they're within the bounds of a comma or at the start or end of a line:
(?:^|,)([a-zA-Z]{2})(?=,|$)
Live preview
var string = "ab,ca,ls,gz,tv";
const regex = /(?:^|,)([a-zA-Z]{2})(?=,|$)/g;
match = regex.exec(string);
while (match != null) {
console.log(match[1]);
match = regex.exec(string);
}
The above outputs:
ab
ca
ls
gz
tv
Try this.
/^[a-z]{2}(,[a-z]{2})*$/i
var string1 = "ab,ca,ls,gz,tv"
var string2 = "ab,c,ls"
var string3 = "ab,ca"
var regex = /^[a-z]{2}(,[a-z]{2})*$/i
document.getElementById("test").innerHTML =
regex.test(string1) + "<br>" + // true
regex.test(string2) + "<br>" + // false
regex.test(string3) // true
<p id="test"></p>
Let data.title be ABC XYZ PQRS - www.aaa.tld.
Output needs to be like this ABC+XYZ
i've tried this:
var t = data.title.split(' ').join('+');
t = t.replace(/(([^\s]+\s\s*){1})(.*)/,"Unknown");
$("#log").text(t);
Here is one way to do it, no regex though, it only grabs the first two words and must have a space between those words.
First we split into and array, then we slice that array from the 0 index to 2(exclusive) or 1, and finally we join them with a '+':
var x = 'ABC XYZ PQRS';
var y = x.split(' ').slice(0,2).join('+');
// y = "ABC+XYZ"
Working Fiddle
Try using .match() with RegExp /([\w+]+)/g; concatenate first match, + character, second match
var matches = "ABC XYZ PQRS - www.aaa.tld".match(/([\w+]+)/g);
console.log(matches[0] + "+" + matches[1])
This is my general function for first n words. Haven't tested it extensively but it is fast even on long strings because it doesn't use a global regex or split every word. You can fine tune the regex for dealing with punctuation. I'm considering a hyphen as a delimiter but you can move that to the word portion instead if you prefer.
function regFirstWords(s, n) {
// ?: non-capturing subsequent sp+word.Change {} if you want to require n instead of allowing fewer
var a = s.match(new RegExp('[\\w\\.]+' + '(?:[\\s-]*[\\w\\.]+){0,' + (n - 1) + '}'));
return (a === undefined || a === null) ? '' : a[0];
}
To satisfy the OP's request to replace with '+'
regFirstWords('ABC XYZ PQRS - www.aaa.tld',2).replace(/\s/g,'+')
var str = "^" + "/post/\d+" + "$";
var regex = new RegExp(str);
var flag = regex.test("/post/3333");
console.log(flag) // -> false
console.log(regex) // -> /^\/post\/d+$/
I'm expecting the result becomes true, but it results in false.
I think the problem is "\" is added automatically before "/" when RegExp instance is created.
How am I supposed to write in order to make it work?
You don't need the new RegExp constructor and string
Here example
var regex = /post\/\d+$/;
var flag = regex.test("/post/3333");
I removed ^ flag, because regex will not work with this format of input "website/post/3333"
Here's a more specific regular expression to match the format of /post/####:
var regex = /\/post\/[0-9]+$/;
var flag = regex.test("/post/3333");
This will test for the string /post/ followed by one or more digits, occurring at the end of the line.
Likewise:
var regex = /\/post\/[0-9]{4}$/;
var flag = regex.test("/post/3333");
will test for the string /post/ followed by 4 digits, occurring at the end of the line.
I'm trying to split a string into an array based on the second occurrence of the symbol _
var string = "this_is_my_string";
I want to split the string after the second underscore. The string is not always the same but it always has 2 or more underscores in it. I always need it split on the second underscore.
In the example string above I would need it to be split like this.
var split = [this_is, _my_string];
var string = "this_is_my_string";
var firstUnderscore = string.indexOf('_');
var secondUnderscore = string.indexOf('_', firstUnderscore + 1);
var split = [string.substring(0, secondUnderscore),
string.substring(secondUnderscore)];
Paste it into your browser's console to try it out. No need for a jsFiddle.
var string = "this_is_my_string";
var splitChar = string.indexOf('_', string.indexOf('_') + 1);
var result = [string.substring(0, splitChar),
string.substring(splitChar, string.length)];
This should work.
var str = "this_is_my_string";
var matches = str.match(/(.*?_.*?)(_.*)/); // MAGIC HAPPENS HERE
var firstPart = matches[1]; // this_is
var secondPart = matches[2]; // _my_string
This uses regular expressions to find the first two underscores, and captures the part up to it and the part after it. The first subexpression, (.*?_.*?), says "any number of characters, an underscore, and again any number of characters, keeping the number of characters matched as small as possible, and capture it". The second one, (_.*) means "match an underscore, then any number of characters, as much of them as possible, and capture it". The result of the match function is an array starting with the full matched region, followed by the two captured groups.
I know this post is quite old... but couldn't help but notice that no one provided a working solution. Here's one that works:
String str = "this_is_my_string";
String undScore1 = str.split("_")[0];
String undScore2 = str.split("_")[1];
String bothUndScores = undScore1 + "_" + undScore2 + "_";
String allElse = str.split(bothUndScores)[1];
System.out.println(allElse);
This is assuming you know there will always be at least 2 underscores - "allElse" returns everything after the second occurrence.