Regex to extract arguments passed into string '#substr( , , )' - javascript

we have a text input where the user can enter some text and apply some functions on top of the text like ( substr , replace ) etc. For example user can enter the text "hello" in the text input and can apply the substring function ( #substr(hello, 'startIndex', 'length'))and can mention the start index and the length etc.
Need to use the regex to extract the values passed into the #substr function for validating the mandatory fields. For example 'start index' and 'length' is required when the user selects the substr function.
Below are the different scenarios and its expected output .
#substr(hello,1,3) ---> ['hello','1','3']
#substr($(sometext),1,3) ---> ['$(sometext)','1','3']
#substr(#trim(hello),1,3) ----> ['#trim(hello)','1','3']
#substr(#replace(hello-world,hello,hi),1,3) ---> ['#replace(hello-world,hello,hi)','1','3']
As from the above examples need to extract the arguments passed into the #substr function as array elements.
Tried this regex
/#substr\((.*?),(.*?),(.*?)\)/g
This fails when we have a nested functions like this - #substr(#replace(hello-world,hello,hi),1,3)

You could use the below regex with capturing groups.
#(\S+?)\((.*)\,(\d+),(\d+)\)
For nested matching, it is not impossible, but much complex in regex. The easy approach should be avoiding regex and using js code for nested matching.

This regex can solve your problems, if the string takes up an entire line, but if you enter comma commands in the second argument, it will fail, this is a very complex problem to solve with simple regex. I think you're knocking on the compilers' door.
regex = /^#substr\((.*),(.*),(.*)\)$/;
text = "#substr(#replace(hello-world,hello,hi),1,3)";
console.log(regex.exec(text));

If you're trying to get the length of user input or index, you could put all the desired methods inside a function or multiple functions that call be called on button-click.
https://www.bitdegree.org/learn/javascript-input
I may be misunderstanding but if I take one of your examples:
#substr(hello,1,3) ---> ['hello','1','3']
When I run
str = "hello world"
str.substring(1,3) --> I get "el" (not "hello", "1", "3")
Get some text:
var firstName = document.getElementById("firstName").value;
var age = document.getElementById("age").value;
Click a button to call your function.
function doSubstringStuff(textValue, subString_mode) {
if subString_mode == "length" {
return textValue.length;
}
OR
Validate the length matches your criteria.
if (textValue.length > 10) {
alert("The name must have no more than 10 characters");
Or Perform other tasks, determined by the argument "mode"
else if subString_mode == "integer_test"{
if (isNaN(textValue) || age < 12 || age > 100){alert("The age must be between numbers 12 and 100")};

Related

How to remove the first zero in a form textbox after first 2 characters in a javascript event?

I want to make sure that the Form Textbox with ID input_1_4 has the right telephone format. To achieve this, every time a user enters a number on the textbox field, the script needs to eliminate the first zero that comes within the first 4 characters.
THIS IS MY JQUERY FUNCTION. What should I put to achieve my goal?
jQuery('#input_1_4').change(function() {
}
});
});
If the user enters +408765432, the script will remove zero because of it within the first 4 characters. The expected result must be +48765432.
If the user enters +4508765432, the result must be +458765432 because it is also within the first 4 characters.
However, if the user enters +4560876543 - The zero will not be removed because it is already the 5th character. The expected result is the same: +4560876543
Try this:
jQuery('#input_1_4').change(function() {
jQuery('#input_1_4').val(jQuery('#input_1_4').val().substring(0,4).replace("0", "")+jQuery('#input_1_4').val().substring(4))
}
});
});
Note: I do not use jQuery that much, nor do I know that this will even run without errors, but hopefully this can give you an idea of what to do:
1. Get the value of the form 2. Get the first four digits of the form (substring) 3. Replace all 0's with empty characters (use regex and replace) 4. Add the remaining digits back in and set the value of the text field.
Hope this helps!
you can try this
var myinput = "+40150544";
function removeit (input) {
var arr = input.split('');
arr.map((x,i)=> { i<4 && x==0 ? arr.splice(i,1) : x})
return arr.join('');
};
removeitit(myinput)
Perhaps the easiest thing would be to take a slice of the first four characters and replace the zero, then concat the rest of the string back together:
function removeZero(s) {
return s.slice(0,4).replace('0', '') + s.slice(4,)
}
let s1 = "+4560876543"
let s2 = "+408765432"
let s3 = "4508765432"
console.log(removeZero(s1))
console.log(removeZero(s2))
console.log(removeZero(s3))
// only removes the first zero
console.log(removeZero("4008765432"))
An alternative is to use a pure regex, thought this is a little harder to debug and read:
function removeZero(s) {
return s.replace(/(^[^0]{0,3})0/, '$1')
}
console.log("+4560876543 => ", removeZero('+4560876543'))
console.log("460876543 => ", removeZero('460876543'))
console.log("0460876543 => ", removeZero('0460876543'))
console.log("+40560876543 => ", removeZero('40560876543'))

Regex to match only certain characters or strings and only one instance of each?

I feel like I know just enough about Regexes to get stuck. That said, I have an input field which will allow users to enter their currency symbol. I'm only wanting to allow said currency symbol and disallow anything else from being entered into that field. Some countries don't actually have a single symbol, but are just two or three characters, e.g., "Kr" for Krona. So the field has a max length of 3. Given it needs a max length of three to accommodate some currencies, I also don't want to allow three dollar signs to be entered, e.g., "$$$". I would only want to allow one single dollar, pound, euro, etc. sign.
Here's my basic code for allowing only these symbos in the input:
$('#id_currency_symbol').on('input',function (){
var value = $(this).val().toString();
newvalue = value.replace(/[^$£€¥₣₩₩¥₽₺₹Rkr]+/g,'');
$(this).val(newvalue);
});
This works for only allowing these symbols/letters, but like I said above, I don't want to allow users to enter more than a single instance of some symbols, i.e. dollar sign ($). In addition, I want to match exact strings for cases where the "symbol" is actually just two or three characters. In the case of Krona, the "symbol" is Kr. Given the above, users could in theory enter "rK" and it would be perfectly valid according to the regex, but I would ONLY want to allow the exact match of "Kr." Is that possible?
Thanks
I would suggest to forget regex, and go for O(1) algos,
var allowedCurrencyCodes = {
"$":true,
"¢":true,
"£":true,
"INR":true,
"Kr":true,
.....,
.....,
.....
}
$(this).val(allowedCurrencyCodes[$(this).val()]?$(this).val():"");
you need to perform the check at blur event or when user has entered at least 3 chars, else it becomes buggy as it will keep on wiping the data right after first char.
if you want to keep check real time i.e. responsive when user is typing in, then you need to change the structure of allowedCurrencyCodes and convert it to nested object for multi-char currency codes, e.g $,£ would be exactly same but INR or Kr will be defined like
"I":{
"N":{
"R":true
}
},
"K":{
"r":true
}
and minor change in fetch logic will be applied, where you will capture input and split it in array and then dip in allowedCurrencyCodes based on input chars, like
allowedCurrencyCodes[inputChar[0]][inputChar[1]]
or
allowedCurrencyCodes[inputChar[0]][inputChar[1]][inputChar[2]]
You may find the first occurrence of a currency symbol or acronym using a regex and then replace the whole input with the matched string. Single character currencies can be listed in [...] and any longer string may be added by alternation:
var checkInput = function(input) {
var regex = /[$£€¥₣₩₩¥₽₺₹]|kr/i;
input = regex.exec(input);
return input == null ? "" : input[0];
}
console.log(checkInput("lkjahfkdshfjsdf Kr asdasda"));
console.log(checkInput("kr"));
console.log(checkInput("rk"));
console.log(checkInput("$$$"));
console.log(checkInput("₣₩₩"));
console.log(checkInput("ABC"));
For completeness:
The "Regex to match only certain characters or strings and only one instance of each":
^(?:[$£€¥₣₩₩¥₽₺₹]|kr)$
Demo: https://regex101.com/r/w9p9d9/1
Regex to strip off anything but "certain characters or strings" and these characters too if they appear more than once (for use within newvalue = value.replace(...,'');):
^(?=.*?([$£€¥₣₩₩¥₽₺₹]|kr)|).*
Demo: https://regex101.com/r/qocsv5/1

HTML5 form validation pattern automatically create a space after first 3 characters?

Using the pattern attribute in HTML forms is it possible to create a space automatically after 3 characters? How can this be accomplished?
pattern="([A-z0-9À-ž\s]){2,}"
The input is just a text field that receives the same data over and over. 3 numbers, 1 space, and then a name. I would like to be able to enter that but get back an extra space after the numbers.
For example:
If I enter: "951 Houston"I would like it to output: "951 Houston" <---extra space after the 3 numbers.
I would like it to be after any characters entered. So if someone were to enter "Houston" it would actually output "Hou ston" Is this possible using the pattern attribute in forms? If so how? If not what is a possible solution? Thanks
A regex can't add a space, so no, this is not possible with just HTML forms. What you would need to do is first extract the word to replace, then use a regex to split the word into a second word after three characters, then add the result back to the DOM:
var textareas = document.getElementsByTagName("textarea");
var str = document.getElementsByTagName("input")[0].value;
var replaced = str.replace(/.{3}/g, function (value, index) {
return value + (index % 5 == 0 ? ' ' : '');
});
textareas[0].value = replaced;
input, textarea {
width:100%
}
<input value="Houston"/>
<textarea></textarea>
In the above example, the string is extracted from the word in question (Houston in an input field, in this case), and replaced contains the string that has been broken into two new words. Simply insert it wherever you would like :)
Hope this helps! :)

Find longest repeating substring in JavaScript using regular expressions

I'd like to find the longest repeating string within a string, implemented in JavaScript and using a regular-expression based approach.
I have an PHP implementation that, when directly ported to JavaScript, doesn't work.
The PHP implementation is taken from an answer to the question "Find longest repeating strings?":
preg_match_all('/(?=((.+)(?:.*?\2)+))/s', $input, $matches, PREG_SET_ORDER);
This will populate $matches[0][X] (where X is the length of $matches[0]) with the longest repeating substring to be found in $input. I have tested this with many input strings and found am confident the output is correct.
The closest direct port in JavaScript is:
var matches = /(?=((.+)(?:.*?\2)+))/.exec(input);
This doesn't give correct results
input Excepted result matches[0][X]
======================================================
inputinput input input
7inputinput input input
inputinput7 input input
7inputinput7 input 7
XXinputinputYY input XX
I'm not familiar enough with regular expressions to understand what the regular expression used here is doing.
There are certainly algorithms I could implement to find the longest repeating substring. Before I attempt to do that, I'm hoping a different regular expression will produce the correct results in JavaScript.
Can the above regular expression be modified such that the expected output is returned in JavaScript? I accept that this may not be possible in a one-liner.
Javascript matches only return the first match -- you have to loop in order to find multiple results. A little testing shows this gets the expected results:
function maxRepeat(input) {
var reg = /(?=((.+)(?:.*?\2)+))/g;
var sub = ""; //somewhere to stick temp results
var maxstr = ""; // our maximum length repeated string
reg.lastIndex = 0; // because reg previously existed, we may need to reset this
sub = reg.exec(input); // find the first repeated string
while (!(sub == null)){
if ((!(sub == null)) && (sub[2].length > maxstr.length)){
maxstr = sub[2];
}
sub = reg.exec(input);
reg.lastIndex++; // start searching from the next position
}
return maxstr;
}
// I'm logging to console for convenience
console.log(maxRepeat("aabcd")); //aa
console.log(maxRepeat("inputinput")); //input
console.log(maxRepeat("7inputinput")); //input
console.log(maxRepeat("inputinput7")); //input
console.log(maxRepeat("7inputinput7")); //input
console.log(maxRepeat("xxabcdyy")); //x
console.log(maxRepeat("XXinputinputYY")); //input
Note that for "xxabcdyy" you only get "x" back, as it returns the first string of maximum length.
It seems JS regexes are a bit weird. I don't have a complete answer, but here's what I found.
Although I thought they did the same thing re.exec() and "string".match(re) behave differently. Exec seems to only return the first match it finds, whereas match seems to return all of them (using /g in both cases).
On the other hand, exec seems to work correctly with ?= in the regex whereas match returns all empty strings. Removing the ?= leaves us with
re = /((.+)(?:.*?\2)+)/g
Using that
"XXinputinputYY".match(re);
returns
["XX", "inputinput", "YY"]
whereas
re.exec("XXinputinputYY");
returns
["XX", "XX", "X"]
So at least with match you get inputinput as one of your values. Obviously, this neither pulls out the longest, nor removes the redundancy, but maybe it helps nonetheless.
One other thing, I tested in firebug's console which threw an error about not supporting $1, so maybe there's something in the $ vars worth looking at.

Regex to extract substring, returning 2 results for some reason

I need to do a lot of regex things in javascript but am having some issues with the syntax and I can't seem to find a definitive resource on this.. for some reason when I do:
var tesst = "afskfsd33j"
var test = tesst.match(/a(.*)j/);
alert (test)
it shows
"afskfsd33j, fskfsd33"
I'm not sure why its giving this output of original and the matched string, I am wondering how I can get it to just give the match (essentially extracting the part I want from the original string)
Thanks for any advice
match returns an array.
The default string representation of an array in JavaScript is the elements of the array separated by commas. In this case the desired result is in the second element of the array:
var tesst = "afskfsd33j"
var test = tesst.match(/a(.*)j/);
alert (test[1]);
Each group defined by parenthesis () is captured during processing and each captured group content is pushed into result array in same order as groups within pattern starts. See more on http://www.regular-expressions.info/brackets.html and http://www.regular-expressions.info/refcapture.html (choose right language to see supported features)
var source = "afskfsd33j"
var result = source.match(/a(.*)j/);
result: ["afskfsd33j", "fskfsd33"]
The reason why you received this exact result is following:
First value in array is the first found string which confirms the entire pattern. So it should definitely start with "a" followed by any number of any characters and ends with first "j" char after starting "a".
Second value in array is captured group defined by parenthesis. In your case group contain entire pattern match without content defined outside parenthesis, so exactly "fskfsd33".
If you want to get rid of second value in array you may define pattern like this:
/a(?:.*)j/
where "?:" means that group of chars which match the content in parenthesis will not be part of resulting array.
Other options might be in this simple case to write pattern without any group because it is not necessary to use group at all:
/a.*j/
If you want to just check whether source text matches the pattern and does not care about which text it found than you may try:
var result = /a.*j/.test(source);
The result should return then only true|false values. For more info see http://www.javascriptkit.com/javatutors/re3.shtml
I think your problem is that the match method is returning an array. The 0th item in the array is the original string, the 1st thru nth items correspond to the 1st through nth matched parenthesised items. Your "alert()" call is showing the entire array.
Just get rid of the parenthesis and that will give you an array with one element and:
Change this line
var test = tesst.match(/a(.*)j/);
To this
var test = tesst.match(/a.*j/);
If you add parenthesis the match() function will find two match for you one for whole expression and one for the expression inside the parenthesis
Also according to developer.mozilla.org docs :
If you only want the first match found, you might want to use
RegExp.exec() instead.
You can use the below code:
RegExp(/a.*j/).exec("afskfsd33j")
I've just had the same problem.
You only get the text twice in your result if you include a match group (in brackets) and the 'g' (global) modifier.
The first item always is the first result, normally OK when using match(reg) on a short string, however when using a construct like:
while ((result = reg.exec(string)) !== null){
console.log(result);
}
the results are a little different.
Try the following code:
var regEx = new RegExp('([0-9]+ (cat|fish))','g'), sampleString="1 cat and 2 fish";
var result = sample_string.match(regEx);
console.log(JSON.stringify(result));
// ["1 cat","2 fish"]
var reg = new RegExp('[0-9]+ (cat|fish)','g'), sampleString="1 cat and 2 fish";
while ((result = reg.exec(sampleString)) !== null) {
console.dir(JSON.stringify(result))
};
// '["1 cat","cat"]'
// '["2 fish","fish"]'
var reg = new RegExp('([0-9]+ (cat|fish))','g'), sampleString="1 cat and 2 fish";
while ((result = reg.exec(sampleString)) !== null){
console.dir(JSON.stringify(result))
};
// '["1 cat","1 cat","cat"]'
// '["2 fish","2 fish","fish"]'
(tested on recent V8 - Chrome, Node.js)
The best answer is currently a comment which I can't upvote, so credit to #Mic.

Categories

Resources