I have this function called vatValidate, which is used to validate VAT format of user inputs. Currently it performs validation for two countries, Austria and Italy as default case. For each, I specified the expected user input sequence for related VAT format with regular expression.
function vatValidate() {
let vatFormat;
let countryCode = document.getElementById('countries').value;
switch (countryCode) {
case 'Austria':
countryCode = 'AT';
vatFormat = /[U]{1}[0-9]{8}/;
break;
default:
countryCode = 'IT';
vatFormat = /[0-9]{11}/;
}
let vatNumber = document.getElementById('pivaid').value;
let vat = countryCode + vatNumber;
if (vatFormat.test(vat)) {
console.log('Correct');
} else {
console.log('Error');
}
}
vatValidate()
If user input matches the predefined sequence, the function logs true else false. It works fine, but the problem is, that the regex code I defined, does not enforce the length of the sequence. As I have studied to do so, for instance for Austria, I have to define the regex using ^ and $ resulting in: /^[U]{1}[0-9]{8}$/
Apparently this should work just fine, as I verified it in regex101.com and can be seen below:
Now the problem is, that as soon as I add ^ and $ in my code, it won't work any longer and it just logs an error! My development environment is Laravel and this code is executed in a script tag inside a blade.
the problem is solved for the case of Austria with THIS REGEX expression:
/^[A]{1}[T]{1}[U]{1}[0-9]{8}$/
Related
I've created a script (my first) that accepts input text and then runs about 30 regular expressions on the text, outputting discovered values into an HTML table. The purpose is for me to be able to paste in text containing specification information for products and have them uniformly outputted so I can paste them into a spreadsheet.
I've had it working really well and I've been tuning the regexes as I've pasted data with different variations/layouts in. However, I've hit an impasse and need some assistance:
One of the regular expressions searches for the product part number (sku) and returns the value in a column. Some of the source data includes more than one match because there are regional variations to the products. In all cases the first match is the only one that I want. I've tested the RegEx on RegEx101 and it returns the first match only with the 'global' flag switched off. However, the same RegEx running in my script causes it to return console messages infinitely before crashing. It's immediately unresponsive so I can't see any error messages.
Here's a sample of the regex section in my script. sku being the one that's causing problems:
let wallMountable = /(?<wallmountable>[Ww]all [Mm]ount)/mg;
let sku = /^.*\((?<sku>\d\d\w\w[\d\w]+?).+?\).*$/m;
function parseData() {
// Execute the Regular Expressions on the text in 'specSheet'
let specSheet = document.getElementById("specSheet").value;
let wallMountableToken = wallMountable.exec(specSheet);
let skuToken = sku.exec(specSheet);
do {
// If Token isn't null, then test to see if the regex group value is undefined. If either are true, do nothing, otherwise write the value to the document.
if (wallMountableToken !== null) {
if (wallMountableToken.groups.wallmountable !== undefined)
{document.write(`${wallMountableToken.groups.wallmountable}`);}
else {}
}
else {}
if (skuToken !== null) {
if (skuToken.groups.sku !== undefined)
{document.write(`${skuToken.groups.sku}`);}
else {}
}
else {}
}
// Loop through the script until a condition is met.
while (
(wallMountableToken = wallMountable.exec(specSheet)) !== null,
(skuToken = sku.exec(specSheet)) !== null
);
}
The while loop may not be necessary and in truth I'm not entirely sure what purpose it serves here, but it seemed to consistently appear in the reference material I was studying. I have included it here because it's part of the script, but please note that the script works if I change the second regex to /mg instead of /m, however, it returns multiple values and I only want it to return the first capture.
I know there's a lot wrong with the script, but this particular question is about why the regex is causing an infinite loop, so any help toward that goal is much appreciated.
I need to implement thousands separator for an input in an Ionic app. I need to achieve this as user types them. I came with following implementation:
In Ts file:
public amount:string; // model
format(){
this.amount=this.separator(this.amount)
}
separator(amount)
{
var num_parts = amount.split(".");
num_parts[0] = num_parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return num_parts.join(".");
}
In html:
<ion-input [(ngModel)]="amount" (keyup)="format()" placeholder="Text Input"></ion-input>
It works fine till number of digit remains 4 (in numeric part).It goes bad when I have more than 4 digit. Since it is called on 'keyup' in second pass it adds another ',' after second digit like this:
1,2,345
And this continues: 1,2,3,455
How Can I get this implemented right i.e. adding thousand separator as user types them.
Thanks for looking into this.
There was problem in my implementation : I was not removing previously added comma. See the comment in following snippet
separator(amount)
{
var num_parts = amount.split(".");
num_parts[0]= num_parts[0].replace(/,/g , ""); // I was not removing previously added comma
num_parts[0] = num_parts[0].replace(/\B(?=(\d{3})+(?!\d))/g, ",");
return num_parts.join(".");
}
I am using the the following function in javascript.
function chknumber(a) {
a.value = a.value.replace(/[^0-9.]/g, '', '');
}
This function replaces any non numeric character entered in a textbox on whose onkeyup i have called the above function. The problem is it allows this string as well
1..1
I want the function to replace the second dot character as well. Any suggestions will be helpful.
I don't advocate simplistically modifying fields while people are trying to type in them, it's just too easy to interfere with what they're doing with simple handlers like this. (Validate afterward, or use a well-written, thoroughly-tested masking library.) When you change the value of a field when the user is typing in it, you mess up where the insertion point is, which is really frustrating to the user. But...
A second replace can correct .. and such:
function chknumber(a) {
a.value = a.value.replace(/[^0-9.]/g, '').replace(/\.{2,}/g, '.');
}
That replaces two or more . in a row with a single one. But, it would still allow 1.1.1, which you probably don't want. Sadly, JavaScript doesn't have lookbehinds, so we get into more logic:
function chknumber(a) {
var str = a.value.replace(/[^0-9.]/g, '').replace(/\.{2,}/g, '.');
var first, last;
while ((first = str.indexOf(".")) !== (last = str.lastIndexOf("."))) {
str = str.substring(0, last) + str.substring(last+1);
}
if (str !== a.value) {
a.value = str;
}
}
Can't guarantee there aren't other edge cases and such, and again, every time you assign a replacement to a.value, you're going to mess up the user's insertion point, which is surprisingly frustrating.
So, yeah: Validate afterward, or use a well-written, thoroughly-tested masking library. (I've had good luck with this jQuery plugin, if you're using jQuery.)
Side note: The second '' in your original replace is unnecessary; replace only uses two arguments.
try with match method if your input is "sajan12paul34.22" the match function will return a array contain [12 , 34.22]
the array index [0] is used for getting first numeric value (12)
function chknumber(a) {
a.value = a.value.match(/[0-9]*\.?[0-9]+/g)[0];
}
I'm doing my calculator and want prevent div to zero. I guess I must check last to elements if they are "/0"? what I'm doing wrong?
function div(input)
{
var input = document.getElementById("t");
var lastElement = (input.value.length-1);
//alert(input.value[lastElement-1]);
//alert(input.value[lastElement]);
if (input.value[lastElement-1] === "/")
{
if (input.value[lastElement] === "0")
{
alert(" / to Zero");
}
}
}
Use RegEx instead:
var is_div_by_zero = /\/[\s.0]+$/.test(value); // Returns true if it is divided by zero, false if otherwise
It matches:
/ 0
/0
/ 0
/ 000
/ 0.00000
etc.
As T.J. Crowder commented it is probably due to inconsistent formatting.
It would be better to work with the Javascript engine instead of going against it.
Just evaluate the entered formula and handle the exceptions thrown by the Javascript engine.
Place your evaluation code inside a try ... catch(e) block and handle the exceptions there.
try {
// your calculation code here, eg:
result = value1 / value2;
} catch (e) {
// this catches the error and provides the proper way of handling the errors,
// and your script doesn't die because of the error
// also, the e parameter contains the exception thrown, which provides info you can
// display
// or based on the error type come up with a proper solution
alert (e.message);
}
More info on Javascript error handling: http://javascript.info/tutorial/exceptions
Update
Forgot that, unfortunately, a division by zero does not result in an exception being thrown in Javascript. It will result in NaN for 0/0 and Infinity for x/0 (where x is any number). Infinity has the type number.
You can test for this after evaluating your equation.
My previous answer is one solution to your problem, but may bee too complicated for what would you like to achieve.
Instead of taking things from your input character by character, split your string on the operator and trim the parts. I will create the solution for two operands, and you can start from that.
var equation = document.getElementById("t").value;
var operands = equation.split('/');
var divisor = operands[operands.length - 1].trim();
// since the contents of your input are a string, the resulting element is also a string
if (parseFloat(divisor) == 0) {
alert("Division by zero");
}
This is a very rough approach, as you will have to validate and filter your input (no other things than numbers and valid operators should be allowed). Also, you will have to check for operation priority (do you allow multiple operators in your equation?) etc.
I'm trying to get parseFloat to convert a userInput (prompt) into a number.
For example:
var userInput = prompt("A number","5,000")
function parse_float(number) {
return parseFloat(number)
}
When userInput = 5,000, parse_Float(userInput) returns 5.
However, if the user was inputting a value to change something else (ie: make a bank deposit or withdrawl) Then I to work properly, parse.Float(userInput) needs to return 5000, not 5.
If anyone could tell me how to do this it would help me so much. Thanks in advance.
Your answer is close, but not quite right.
replace doesn't change the original string; it creates a new one. So you need to create a variable to hold the new string, and call parseFloat on that.
Here's the fixed code:
function parseFloatIgnoreCommas(number) {
var numberNoCommas = number.replace(/,/g, '');
return parseFloat(numberNoCommas);
}
I also renamed the function to parseFloatIgnoreCommas, which better describes what it does.
This is the function I use to scrub my user inputted numbers from a form. It handles anything a user may put in with a number like $ or just accidentally hitting a key.
I copied the following out of an object:
cleanInput : function(userValue){
//clean the user input and scrub out non numerals
var cleanValue = parseFloat(userValue.replace(/[^0-9\.]+/g,""));
return cleanValue;
},
To make it non-object just change the first line to cleanInput(){....
I have put together info from the comments to form a basic answer:
The answer seems to simply be to set parse_float to run :
number.replace(/,/g, "")
return parseFloat(number)
The complete code would look like this:
var userInput = prompt("A number","523,000,321,312,321")
function parse_float(number) {
number.replace(/,/g, "")
return parseFloat(number)
}
returns: 523000321312321