Regex decimal values between 0 and 1 up to 4 decimal places - regex

I am writing a C# web application and verify data in a textbox using this regular expression that only accepts positive decimal values between 0 and 1:
^(0(\.\d+)?|1(\.0+)?)$
I would to adapt like the regex to restrict entries to 4 decimal places of precision.
Allowed
0
0.1
0.12
0.123
0.1234
1
Not allowed
-0.1
-1
1.1
2
I have found the following regex that only allows up to 4 decimal places, but I am unsure on how to combine the two.
^(?!0\d|$)\d*(\.\d{1,4})?$
Any help is greatly appreciated, thanks.

You need to set replace the + quantifier with the limiting {1,4}:
^(0(\.[0-9]{1,4})?|1(\.0{1,4})?)$
^^^^^ ^^^^^
See the regex demo
Details:
^ - start of string
( - Outer group start
0 - a zero
(\.[0-9]{1,4})? - an optional sequence of a . followed with 1 to 4 digits
| - or
1 - a 1
(\.0{1,4})?) - an optional sequence of . followed with 1 to 4 zeros
$ - end of string.

This can be used as the validation function that allows four digit decimal place in terms of regular expession (RegExp).
function fourdecimalplace(e) {
var val = this.value;
var re = /^([0-9]+[\.]?[0-9]?[0-9]?[0-9]?[0-9]?|[0-9]+)$/g;
var re1 = /^([0-9]+[\.]?[0-9]?[0-9]?[0-9]?[0-9]?|[0-9]+)/g;
if (re.test(val)) {
//do something here
} else {
val = re1.exec(val);
if (val) {
this.value = val[0];
} else {
this.value = "";
}
}

Related

RegEx vscode - replace decimal places and round correctly

Is it possible to use regex to round decimal places?
I have lines that look like this but without any spaces (space added for readability).
0, 162.3707542, -162.3707542
128.2, 151.8299471, -23.62994709 // this 151.829 should lead to 151.83
I want to remove all numbers after the second decimal position and if possible round the second decimal position based on the third position.
0, 162.37, -162.37
128.2, 151.82, -23.62 // already working .82
..., 151.83, ... // intended .83 <- this is my question
What is working
The following regex (see this sample on regex101.com) almost does what i want
([0-9]+\.)([0-9]{2})(\d{0,}) // search
$1$2 // replace
My understanding
The search works like this
group: ([0-9]+\.) find 1 up to n numbers and a point
group: ([0-9]{2}) followd by 2 numbers
group: (\d{0,}) followed by 0 or more numbers / digits
In visual-studio-code in the replacement field only group 1 and 2 are referenced $1$2.
This results in this substitution (regex101.com)
Question
Is it possible to change the last digit of $2 (group two) based on the first digit in $3 (group three) ?
My intention is to round correctly. In the sample above this would mean
151.8299471 // source
151.82 // current result
151.83 // desired result 2 was changed to 3 because of third digit 9
It is not only that you need to update the digit of $2. if the number is 199.995 you have to modify all digits of your result.
You can use the extension Regex Text Generator.
You can use a predefined set of regex's.
"regexTextGen.predefined": {
"round numbers": {
"originalTextRegex": "(-?\\d+\\.\\d+)",
"generatorRegex": "{{=N[1]:fixed(2):simplify}}"
}
}
With the same regex (-?\\d+\\.\\d+) in the VSC Find dialog select all number you want, you can use Find in Selection and Alt+Enter.
Then execute the command: Generate text based on Regular Expression.
Select the predefined option and press Enter a few times. You get a preview of the result, you can escape the UI and get back the original text.
In the process you can edit generatorRegex to change the number of decimals or to remove the simplify.
It was easier than I thought, once I found the Number.toFixed(2) method.
Using this extension I wrote, Find and Transform, make this keybinding in your keybindings.json:
{
"key": "alt+r", // whatever keybinding you want
"command": "findInCurrentFile",
"args": {
"find": "(-?[0-9]+\\.\\d{3,})", // only need the whole number as one capture group
"replace": [
"$${", // starting wrapper to indicate a js operation begins
"return $1.toFixed(2);", // $1 from the find regex
"}$$" // ending wrapper to indicate a js operation ends
],
// or simply in one line
// "replace": "$${ return $1.toFixed(2); }$$",
"isRegex": true
},
}
[The empty lines above are there just for readability.]
This could also be put into a setting, see the README, so that a command appears in the Command Palette with the title of your choice.
Also note that javascript rounds -23.62994709 to -23.63. You had -23.62 in your question, I assume -23.63 is correct.
If you do want to truncate things like 4.00 to 4 or 4.20 to 4.2 use this replace instead.
"replace": [
"$${",
"let result = $1.toFixed(2);",
"result = String(result).replace(/0+$/m, '').replace(/\\.$/m, '');",
"return result;",
"}$$"
],
We are able to round-off decimal numbers correctly using regular expressions.
We need basically this regex:
secondDD_regx = /(?<=[\d]*\.[\d]{1})[\d]/g; // roun-off digit
thirdDD_regx = /(?<=[\d]*\.[\d]{2})[\d]/g; // first discard digit
isNonZeroAfterThirdDD_regx = /(?<=[\d]*\.[\d]{3,})[1-9]/g;
isOddSecondDD_regx = /[13579]/g;
Full code (round-off digit up to two decimal places):
const uptoOneDecimalPlaces_regx = /[\+\-\d]*\.[\d]{1}/g;
const secondDD_regx = /(?<=[\d]*\.[\d]{1})[\d]/g;
const thirdDD_regx = /(?<=[\d]*\.[\d]{2})[\d]/g;
const isNonZeroAfterThirdDD_regx = /(?<=[\d]*\.[\d]{3,})[1-9]/g;
const num = '5.285';
const uptoOneDecimalPlaces = num.match(uptoOneDecimalPlaces_regx)?.[0];
const secondDD = num.match(secondDD_regx)?.[0];
const thirdDD = num.match(thirdDD_regx)?.[0];
const isNonZeroAfterThirdDD = num.match(isNonZeroAfterThirdDD_regx)?.[0];
const isOddSecondDD = /[13579]/g.test(secondDD);
// check carry
const carry = !thirdDD ? 0 : thirdDD > 5 ? 1 : thirdDD < 5 ? 0 : isNonZeroAfterThirdDD ? 1 : isOddSecondDD ? 1 : 0;
let roundOffValue;
if(/9/g.test(secondDD) && carry) {
roundOffValue = (Number(`${uptoOneDecimalPlaces}` + `${secondDD ? Number(secondDD) : 0}`) + Number(`0.0${carry}`)).toString();
} else {
roundOffValue = (uptoOneDecimalPlaces + ((secondDD ? Number(secondDD) : 0) + carry)).toString();
}
// Beaufity output : show exactly 2 decimal places if output is x.y or x
const dd = roundOffValue.match(/(?<=[\d]*[\.])[\d]*/g)?.toString().length;
roundOffValue = roundOffValue + (dd=== undefined ? '.00' : dd === 1 ? '0' : '');
console.log(roundOffValue);
For more details check: Round-Off Decimal Number properly using Regular Expression🤔

Regex for float numbers with two decimals in 0-1 range

I am trying to make a HTML pattern / regex to allow only float numbers between 0 and 1 with maximum two decimals.
So, the following will be correct:
0
0.1
0.9
0.11
0.99
1
And these will be incorrect:
00
0.111
0.999
1.1
2
10
I have no knowledge of regex and I don't understand its syntax and I haven't found one online tool to generate a regex.
I've come with something from what I've gathered from online examples:
^(0[0-1]|\d)(\.\d{1,2})?$
I have added 0[0-1] to set a 0-1 range but it does not work. This regex matches every number between 0 and 9 that can also have maximum 2 decimals.
Try using an alternation where the 0 part can be followed by an optional dot and 2 digits and the 1 part can be followed by an optional dot and 1 or 2 times a zero.
^(?:0(?:\.\d{1,2})?|1(?:\.0{1,2})?)$
^ Start of string
(?: Non capturing group
0(?:\.\d{1,2})? Match 0 and optionally a dot and 1-2 digits
| Or
1(?:\.0{1,2})? Match 1 and optionally a dot and 1-2 zeroes
) Close group
$ End of string
Regex demo
If you are not ease with RegEx, you can use some code to check if the input corresponds with your needs, such as :
function ValidateNumber(num)
{
const floatNumber = Number(num);
return floatNumber != NaN && 0 <= floatNumber && floatNumber <= 1 && ('' + num).length <= 4;
}
const TestArray = [ '42', 42, 0, '0', '1', '1.00', '1.01', '0.01', '0.99', '0.111', 'zero' ]
TestArray.forEach(function(element) {
console.log(element + ' is ' + (ValidateNumber(element) ? '' : 'not ') + 'a valid number');
});

Regex for set of 6 digits from 1-49

I've a problem with define regular expression correctly. I want check sets of digits f.e.: 1,2,14,15,16,17 or 12,13,14,15,16,17 or 1,2,3,6,7,8. Every set contains 6 digits from 1 to 49. I check it by input's pattern field.
I wrote some regex but it works only for 2-digit sets.
([1-9]|[1-4][0-9],){5}([1-9]|[1-4][0-9])
Thanks for all answers :)
You forgot to group the number patterns inside the quantified group before comma and the anchors to make the regex engine match the full input string:
^(?:(?:[1-9]|[1-4][0-9]),){5}(?:[1-9]|[1-4][0-9])$
^ ^^^ ^ ^
See the regex demo.
Details
^ - start of string
(?:(?:[1-9]|[1-4][0-9]),){5} - five occurrences of:
(?:[1-9]|[1-4][0-9]) - either a digit from 1 to 9 or a number from 10 to 49`
, - a comma
(?:[1-9]|[1-4][0-9])
$ - end of string.
JS demo:
var strs = ['1,2,14,15,16,17','12,13,14,15,16,17', '1,2,3,6,7,8', '1,2,3,6,7,8,'];
var rng = '(?:[1-9]|[1-4][0-9])';
var rx = new RegExp("^(?:" + rng + ",){5}" + rng + "$");
for (var s of strs) {
console.log(s, '=>', rx.test(s));
}

Replace fractions to decimals in string

I need to replace fraction in given string to decimal.
So:
1/4 xx -> 0.25 xx
1/3 xx -> 0.33 xx
Above exampels I got covered with:
private fun String.replaceFractions() = "(?:[1-9]*)/[1-9]*".toRegex().find(this)
?.let {
val fraction = it.groups[0]!!.value
val fractionParts = fraction.split("/")
.map { part -> part.toDouble() }
this.replace(fraction, (fractionParts[0] / fractionParts[1]).toString())
}
?: this
But I cannot find a way to replace properly string when they also have whole part:
1 1/4 xx -> 1.25 xx
3 3/5 xx -> 3.6 xx
You may achieve what you want with a mere replace like
val s = "Some text: 1/4 and 3 3/5"
val result = s.replace("""(?:(\d+(?:\.\d+)?)\s+)?(\d+)/(\d+)""".toRegex()) {
((if (it.groupValues[1].isNullOrEmpty()) 0.0 else it.groupValues[1].toDouble()) + (it.groupValues[2].toDouble() / it.groupValues[3].toDouble())).toString()
}
println(result) // => Some text: 0.25 and 3.6
See Kotlin demo
Regex details
(?:(\d+(?:\.\d+)?)\s+)? - an optional non-capturing group matching 1 or 0 occurrences of:
(\d+(?:\.\d+)?) - Group 1: 1+ digits, and then 1 or 0 (optional) sequence of . and 1+ digits
\s+ - 1+ whitespaces
(\d+) - Group 2: 1+ digits
/ - a / char
(\d+) - Group 3: 1+ digits
If Group 1 matched, its value is cast to double, else, 0 is taken, and the value is summed with the result of Group 2 and Group 3 division.

Remove first zero values from string using regex

I've created a string value using padStart method (padLeft), for example:
"5".padStart(19, "0")
which results into "0000000000000000005"
How can I get that 5 back using regex?
I've tested this:
/^0*(\d+)$/.exec(d)[1]
which return 5 correctly.
But this regex returns null for something like "00000012.22"
Samples:
5 > 5
005 > 5
0011.22 > 11.22 >> This is a first problem!
00100 >> 100
001001 >> 1001
00.5 >> 0.5 This is a second problem!
Working codes but without regex:
function toDb(d) {
if (d == null) return null;
var precisionIndex = d.indexOf('.');
return d.toString().padStart((29 + precisionIndex + 1), '0');
}
function fromDb(d) {
if (d == null) return null;
d = d.replace(/^0+/, ''); // I'd like to use regex here
if (d.indexOf('.') == 0) // I'd like to use regex here
d = '0' + d; // I'd like to use regex here
return d;
}
fromDb(toDb('0.5')) returns 0.5 for me. But I'd like to use regex in my codes.
Use String#replace method to replace leading 0.
console.log(
"0000000000000000005".replace(/^0+(?=\d)/, '')
)
console.log(
"000000000000000000.5".replace(/^0+(?=\d)/, '')
)
In the regex start anchor(^) assert the beginning position of the string and 0+ matches combination one or more repetition of 0, altogether ^0+ matches 0s at the beginning.
UPDATE : To avoid removing 0 just before the . use positive look ahead assertion, (?=\d) match up to the 0 which follows a digit.