Replace fractions to decimals in string - regex

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.

Related

Capture 1-9 after the last occurrence of 0

I want to capture all numbers between 1 and 9 after the last occurrence of zero except zero in the last digit. I tried this pattern it seems that it doesn’t work.
Pattern: [1-9].*
DATA
0100179835
3000766774
1500396843
1500028408
1508408637
3105230262
3005228061
3105228407
3105228940
0900000000
2100000000
0800000000
1000000001
2200000001
0800000001
1300000001
1000000002
2200000002
0800000002
1300000002
1000000003
2200000003
0800000003
1300000003
1000000004
2200000004
0800000004
1300000004
1000000005
2200000005
0800000005
1300000005
1000000006
2300000006
0800000006
0900000006
1000000007
2300000007
0900000007
0800000007
1000000008
2300000008
0900000008
0800000008
1100000009
2300000009
0900000009
0800000009
1000005217
2000000429
1100000020
1000005000
3000000070
2000000400
1000020000
3000200000
2906000000
Desired Result
179835
766774
396843
28408
8408637
5230262
5228061
5228407
5228940
0
0
0
1
1
1
1
2
2
2
2
3
3
3
3
4
4
4
4
5
5
5
5
6
6
6
6
7
7
7
7
8
8
8
8
9
9
9
9
5217
429
20
5000
70
400
20000
200000
6000000
You can anchor the end of the string and match non-zero digits with an optional trailing zero. Ensure that there is at least one matching digit with a positive lookahead pattern:
(?=\d)[1-9]*0?$
Demo: https://regex101.com/r/uggV37/2
To get desired result:
(?:^0*[1-9]+0*\K0|0\K[1-9]+(?:0[1-9]*|0+)?)$
Explanation
(?: Non capture group for the alternatives
^ Start of string
0*[1-9]+0* Match 1+ digits 1-9 between optional zeroes
\K0 Forget what is matched so far and then match a zero
| Or
0\K Match a zero and forget what is matched so far
[1-9]+ Match 1+ digits 1-9
(?: Non capture group for the alternatives
0[1-9]* Match a zero and optional digits 1-9
| Or
0+ Match 1+ zeroes
)? Close the non capture group
) Close the non capture gruop
$ End of string
See a regex demo.
Match 1 item each line:
'0123056'.match(/(?<=0)[1-9]*0?$/g).filter(m => m != '')
Match multiple item each line:
'0123056 0000210 1205000 1204566 0123456 0012340 0123400'.match(/(?<=0)[1-9]*0?\b/g).filter(m => m != '')

Valid regex for number(a,b) format

How can I express number(a,b) in regex? Example:
number(5,2) can be 123.45 but also 2.44
The best I got is: ([0-9]{1,5}.[0-9]{1,2}) but it isn't enough because it wrongly accepts 12345.22.
I thought about doing multiple OR (|) but that can be too long in case of a long format such as number(15,5)
You might use
(?<!\S)(?!(?:[0-9.]*[0-9]){6})[0-9]{1,5}(?:\.[0-9]{1,2})?(?!\S)
Explanation
(?<!\S) Negative lookbehind, assert what is on the left is not a non whitespace char
(?! Negative lookahead, assert what is on the right is not
(?:[0-9.]*[0-9]){6} Match 6 digits
) Close lookahead
[0-9]{1,5} Match 1 - 5 times a digit 0-9
(?:\.[0-9]{1,2})? Optionally match a dot and 1 - 2 digits
(?!\S) Negative lookahead, assert what is on the right is not a non whitespace char
Regex demo
I don't know Scala, but you would need to input those numbers when building your regular expression.
val a = 5
val b = 2
val regex = (raw"\((?=\d{1," + a + raw"}(?:\.0+)?|(?:(?=.{1," + (a + 1) + "}0*)(?:\d+\.\d{1," + n + "})))‌.+\)").r
This checks for either total digits is 5, or 6 (including decimal) where digits after the decimal are a max of 2 digits. For the above scenario. Of course, this accounts for variable numbers for a and b when set in code.

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');
});

c# Regex mask for textbox decimal precision 1 min value 1 max value 100

Does anyone has the regex mask for a textbox where it allows decimal precision 1 with min value of 1 and max value of 100.
Values that need to pass:
0,5
0,1
10,5
99,5
100
basicly every value between 0,1 and 100
Give this pattern a try
\d{0,3},?\d*
Pattern breakdown:
\d{0,3} - 0 to 3 digits
,? - 0 to 1 comma
\d* - 0 or more digits
Tested at Regex101
To match every value between 0,1 and 100 and allow a decimal precision of 1, you could match either: 100 with an optional ,0 or 1 - 99 with an optional 1 decimal precision of 0-9 or match a 0 with 1 decimal precision from 1-9 so it does not match 0,0 using an alternation.
^(?:[1-9][0-9]?(?:,[0-9])?|0,[1-9]|(?:100(?:,0)?))$
Explanation
^ Assert start of the line
(?: Non capturing group
[1-9][0-9]?(?:,[0-9] Match 1 - 99 followed by an optional comma and digit 0-9
| Or
0,[1-9] Match a zero and a comma followed by a digit 1-9 so 0,0 does not match
| Or
(?:100(?:,0)?) Match 100 with an optional comma and 0
) Close non capturing group
$ Assert end of the line
Demo

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

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 = "";
}
}