Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 14 days ago.
This post was edited and submitted for review 14 days ago.
Improve this question
I have an <input type='number'/> element.
I would like to perform a transformation on the number that is input when the submit event triggers. It could be on another event also: I'm open to suggestions, but the transformation should not happen while the user is typing, only when they finish their input.
The transformation should be as follows:
Remove all leading zeros
Remove all ending zeros
Replace all other consecutive zeroes with just one or two zeroes (depending on a variable it should be one or two)
For example: 01002000400 will be converted to 10204
The third rule depends on a boolean variable first_user: if it's true then all inside consecutive zeroes will be converted to one zero, if it's false all inside zeroes will be converted to two zeroes.
Attempt
Here is what I've tried:
ref.value.replace('/^0+/', '')
To also remove the ending zeroes, I tried ^0$, but it didn't work out as I intended: there was no effect.
And I have no idea how to implement the third rule.
How can I achieve this?
You can do this with a single replace call. The three cases can be checked in this order:
Zeroes at start of string
Zeroes at end of string
Zeroes (more than one) anywhere else: capture the first zero in capture group
As replacement, output the string captured by the capture group. As this group only captures a zero when the third case kicks in, this practically means that all other zeroes are removed.
I believe an exception to this rule has to be introduced for when the number is exactly 0. I guess you want to keep that single zero then. To make that happen, I would restrict the first two rules as follows:
Zeroes at start of string when followed by a non-zero
Zeroes at end of string when following a non-zero
Zeroes (more than one) anywhere else: capture the first zero in capture group
The third case will now also apply when the input consists of only zeroes.
You could use the submit event, but maybe it is interesting too to use the change event: it does not trigger while the user is typing, but does trigger when the user "commits" the value, i.e. when focus is moved to another element, or another tab/window is selected, or the up/down controls are used on the input widget, or the form is submitted, ...
const inputDouble = document.getElementById("double")
const input = document.getElementById("inp");
document.addEventListener("change", function () {
const regex = inputDouble.checked
? /^0+(?=[^0])|(?<=[^0])0+$|(00)0+/g
: /^0+(?=[^0])|(?<=[^0])0+$|(0)0+/g
input.value = input.value.replace(regex, "$1");
});
<input id="double" type="checkbox"> Double zeroes<br>
Number to clean: <input id="inp" type="number"><br>
<button>Fake submit</button>
A good solution would be to implement a simple algorithm that does what you need. Example:
Remove from the first position (0) on until you find a non-zero number;
Remove from the last position backwards (string.length-1) until you find a non-zero number;
Walk the string after the modification above and: if the current number is a non-zero create a new string with it, if it is zero and the previous was not, include it on the new string, if the previous was zero, ignore it.
That should make a very simple method and will work better then a regex.
For the onSubmit trigger, I think it will work fine. I would use onChange and store it in a hidden field just, but I thing onSubmit will do the trick
I think you're overthinking it. To replace multiples of anything with a single version of that thing you just need to target one or more things and in your replace function, replace with a single thing
You don't really need to specify the beginning or the end. You just need to specify any one or more 0 and then replace with a single 0
Try this:
const singleZeros = '10020004'.replace(/(0+)/g, '0')
console.log(singleZeros);
For removing the leading and trailing 0's, there might be a better way but off the top of my head, this is what I'd do:
const removeStart = (s) => s.startsWith('0') ? s.slice(1) : s;
const removeEnd = (s) => s.endsWith('0') ? s.slice(0, s.length - 1) : s;
const zerosOnEnds = '0102040'
const zerosTrimmed = removeEnd(removeStart(zerosOnEnds));
console.log(zerosTrimmed)
Maybe a simple solution would be to create a conversion function to run on submit. Something like:
answer = 10020004
function transform(answer){
final_answ = ''
index = 0
zero_index = -2
while(index<answer.toString().length){
if (answer.toString()[index] !== '0'){
final_answ += answer.toString()[index]
} else if (index === zero_index+1){
zero_index = index
} else {
final_answ += answer.toString()[index]
zero_index = index
}
index++
}
}
Transforming the user response to string will also make it easy for you to remove starting and ending '0'.
If this does not help will you please, provide more information?
Hope it helps.
You can try this
let str = '001002000400'
str = str.replace(/^0*(\d+?)0*$/, (matchs, p1) => {
return p1.replaceAll(/([^0]+)0+/g,'$10')
})
console.log(str); //10204
from your post all you need is just a regex to replace first zero with empty string and other zero in middle if they're more than 1 replace them and just keep one
what you will be need first thing in your code you're used the regex as string'/^0+/' and that's not the true way to use regex you should remove the string quotes and write your regex inside forward slash / like /regex/
second: you need to use regex modifiers in your case you need g modifier
for more info about regex you can check some tutorials like that or quick reference like w3schools reference
here's your regex
//Result: 104057
console.log("0100400057".replace(/^0|(0)+(?=0)/g, ""))
Related
I've written a basic 2 operand calculator app (+ - * /) that uses a couple of inline regex validations to filter away invalid characters as they are typed.
An example looks like:
//check if operator is present
if(/[+\-*\/]/.test(display1.textContent)){
//validate the string each time a new character is added
if(!/^\d+\.?\d*[+\-*\/]?\d*\.?\d*$/.test(display1.textContent)){
console.log('invalid')
return false
}
//validate the string character by character before operator
} else {
if(!/^\d+\.?\d*$/.test(display1.textContent)){
console.log('invalid')
return false
}
}
In the above, a valid character doesn't return false:
23.4x0.00025 (no false returned and hence the string is typed out)
But, if an invalid character is typed the function returns false and the input is filtered away:
23.4x0.(x) x at the end returns a false so is filtered (only one operator allowed per calculation)
23.4x0. is typed
It works pretty well but allows for the following which I would like to deal with:
2.+.1
I would prefer 2.0+0.1
My regex would need an if-then-else conditional stating that if the current character is '.' then the next character must be a number else the next char can be number|.|operator. Or if the current character is [+-*/] then the next character must be a number, else the next char can be any char (while following the overall logic).
The tricky part is that the logic must process the string as it is typed character by character and validate at each addition (and be accurate), not at the end when the string is complete.
if-then-else regex is not supported in JavaScript (which I think would satisfy my needs) so I need to use another approach whilst remaining within the JS domain.
Any suggestions about this specific problem would be really helpful.
Thanks
https://github.com/jdineley/Project-calculator
Thanks #trincot for the tips using capturing groups and look around. This helped me write what I needed:
https://regex101.com/r/khUd8H/1
git hub app is updated and works as desired. Now just need to make it pretty!
For ensuring that an operator is not allowed when the preceding number ended in a point, you can insert a positive look behind in your regex that requires the character before an operator to always be a digit: (?<=\d)
Demo:
const validate = s => /^(\d+(\.\d*)?((?<=\d)[+*/-]|$))*$/.test(s);
document.querySelector("input").addEventListener("input", function () {
this.style.backgroundColor = validate(this.value) ? "" : "orange";
});
Input: <input>
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'))
I guess that should be smth very easy, but I'm stuck with that for at least 2 hours and I think it's better to ask the question here.
So, I've got a reg expression /&t=(\d*)$/g and it works fine while it is not ?t instead of &t in url. I've tried different combinations like /\?|&t=(\d*)$/g ; /\?t=(\d*)$|/&t=(\d*)$/g ; /(&|\?)t=(\d*)$/g and various others. But haven't got the expected result which is /\?t=(\d*)$/g or /&t=(\d*)$/g url part (whatever is placed to input).
Thx for response. I think need to put some details here. I'm actually working on this peace of code
var formValue = $.trim($("#v").val());
var formValueTime = /&t=(\d*)$/g.exec(formValue);
if (formValueTime && formValueTime.length > 1) {
formValueTime = parseInt(formValueTime[1], 10);
formValue = formValue.replace(/&t=\d*$/g, "");
}
and I want to get the t value whether reference passed with &t or ?t in references like youtu.be/hTWKbfoikeg?t=82 or similar one youtu.be/hTWKbfoikeg&t=82
To replace, you may use
var formValue = "some?some=more&t=1234"; // $.trim($("#v").val());
var formValueTime;
formValue = formValue.replace(/[&?]t=(\d*)$/g, function($0,$1) {
formValueTime = parseInt($1,10);
return '';
});
console.log(formValueTime, formValue);
To grab the value, you may use
/[?&]t=(\d*)$/g.exec(formValue);
Pattern details
[?&] - a character class matching ? or &
t= - t= substring
(\d*) - Group 1 matching zero or more digits
$ - end of string
/\?t=(\d*)|\&t=(\d*)$/g
you inverted the escape character for the second RegEx.
http://regexr.com/3gcnu
I want to thank you all guys for trying to help. Special thanks to #Wiktor Stribiżew who gave the closest answer.
Now the piece of code I needed looks exactly like this:
/[?&]t=(\d*)$/g.exec(formValue);
So that's the [?&] part that solved the problem.
I use array later, so /\?t=(\d*)|\&t=(\d*)$/g doesn't help because I get an array like [t&=50,,50] when reference is & type and the correct answer [t?=50,50] when reference is ? type just because of the order of statements in RegExp.
Now, if you're looking for a piece of RegExp that picks either character in one place while the rest of RegExp remains the same you may use smth like this [?&] for the example where wanted characters are ? and &.
I am trying to extract the first character after the last underscore in a string with an unknown number of '_' in the string but in my case there will always be one, because I added it in another step of the process.
What I tried is this. I also tried the regex by itself to extract from the name, but my result was empty.
var s = "XXXX-XXXX_XX_DigitalF.pdf"
var string = match(/[^_]*$/)[1]
string.charAt(0)
So the final desired result is 'D'. If the RegEx can only get me what is behind the last '_' that is fine because I know I can use the charAt like currently shown. However, if the regex can do the whole thing, even better.
If you know there will always be at least one underscore you can do this:
var s = "XXXX-XXXX_XX_DigitalF.pdf"
var firstCharAfterUnderscore = s.charAt(s.lastIndexOf("_") + 1);
// OR, with regex
var firstCharAfterUnderscore = s.match(/_([^_])[^_]*$/)[1]
With the regex, you can extract just the one letter by using parentheses to capture that part of the match. But I think the .lastIndexOf() version is easier to read.
Either way if there's a possibility of no underscores in the input you'd need to add some additional logic.
Friends,
I'm new to both Javascript and Regular Expressions and hope you can help!
Within a Javascript function I need to check to see if a comma(,) appears 1 or more times. If it does then there should be one or more numbers either side of it.
e.g.
1,000.00 is ok
1,000,00 is ok
,000.00 is not ok
1,,000.00 is not ok
If these conditions are met I want the comma to be removed so 1,000.00 becomes 1000.00
What I have tried so is:
var x = '1,000.00';
var regex = new RegExp("[0-9]+,[0-9]+", "g");
var y = x.replace(regex,"");
alert(y);
When run the alert shows ".00" Which is not what I was expecting or want!
Thanks in advance for any help provided.
strong text
Edit
strong text
Thanks all for the input so far and the 3 answers given. Unfortunately I don't think I explained my question well enough.
What I am trying to achieve is:
If there is a comma in the text and there are one or more numbers either side of it then remove the comma but leave the rest of the string as is.
If there is a comma in the text and there is not at least one number either side of it then do nothing.
So using my examples from above:
1,000.00 becomes 1000.00
1,000,00 becomes 100000
,000.00 is left as ,000.00
1,,000.00 is left as 1,,000.00
Apologies for the confusion!
Your regex isn't going to be very flexible with higher orders than 1000 and it has a problem with inputs which don't have the comma. More problematically you're also matching and replacing the part of the data you're interested in!
Better to have a regex which matches the forms which are a problem and remove them.
The following matches (in order) commas at the beginning of the input, at the end of the input, preceded by a number of non digits, or followed by a number of non digits.
var y = x.replace(/^,|,$|[^0-9]+,|,[^0-9]+/g,'');
As an aside, all of this is much easier if you happen to be able to do lookbehind but almost every JS implementation doesn't.
Edit based on question update:
Ok, I won't attempt to understand why your rules are as they are, but the regex gets simpler to solve it:
var y = x.replace(/(\d),(\d)/g, '$1$2');
I would use something like the following:
^[0-9]{1,3}(,[0-9]{3})*(\.[0-9]+)$
[0-9]{1,3}: 1 to 3 digits
(,[0-9]{3})*: [Optional] More digit triplets seperated by a comma
(\.[0-9]+): [Optional] Dot + more digits
If this regex matches, you know that your number is valid. Just replace all commas with the empty string afterwards.
It seems to me you have three error conditions
",1000"
"1000,"
"1,,000"
If any one of these is true then you should reject the field, If they are all false then you can strip the commas in the normal way and move on. This can be a simple alternation:
^,|,,|,$
I would just remove anything except digits and the decimal separator ([^0-9.]) and send the output through parseFloat():
var y = parseFloat(x.replace(/[^0-9.]+/g, ""));
// invalid cases:
// - standalone comma at the beginning of the string
// - comma next to another comma
// - standalone comma at the end of the string
var i,
inputs = ['1,000.00', '1,000,00', ',000.00', '1,,000.00'],
invalid_cases = /(^,)|(,,)|(,$)/;
for (i = 0; i < inputs.length; i++) {
if (inputs[i].match(invalid_cases) === null) {
// wipe out everything but decimal and dot
inputs[i] = inputs[i].replace(/[^\d.]+/g, '');
}
}
console.log(inputs); // ["1000.00", "100000", ",000.00", "1,,000.00"]