Regex for currency formatting - java - java

I want to add the filter to my EditText with accepts different currency values like,
US currency format: 123,456.00
Spanish currency format: 123.456,00
Also, I want to keep maximum 10 digits before the decimal point and max 2 digits after the decimal.
My regex for filtering EditText value is (([0-9|(,.)]{0,13})?)?((,.)[0-9]{0,2})?
But this regex accepts values like ,,,,,,, or .......
How to change this regex which strictly accepts both currency format with the same pattern?
Any help is appreciated. Thank you in advance.

Your pattern could match repeating dots or repeating comma's only because all the parts are optional due to the question mark. It could also match an empty string.
You could use an alternation with a repeating group that starts with a dot or comma followed by 3 or 2 digits to prevent consecutive dots and commas:
Explanation
^(?:(?![,0-9]{14})\d{1,3}(?:,\d{3})*(?:\.\d{1,2})?|(?![.0-9]{14})\d{1,3}(?:\.\d{3})*(?:\,\d{1,2})?)$
^ Start of string
(?: Non capturing group
(?![,0-9]{14}) Negative lookahead, assert not repeating 14 times a comma or digit
\d{1,3}(?:,\d{3})*(?:\.\d{1,2})? Match 1-3 digits, repeat 0+ times matching a comma followed by 3 digits, optionally match a dot and 1-2 digits
| Or
(?![.0-9]{14}) Negative lookahead, assert not repeating 12 times a dot or digit
\d{1,3}(?:\.\d{3})*(?:\,\d{1,2})? Match 1-3 digits, repeat 0+ times matching a dot followed by 3 digit, optionally match a comma and 1-2 digits
) Close non capturing group
$ Assert end of string
Regex demo

NumberFormat's getCurrencyInstance method has a Locale parameter. This is the standard way to handle your problem of formatting currencies.

Related

how to create a regular expression to validate the numbers are not same even separated by hyphen (-)

Using the following regex
^(\d)(?!\1+$)\d{3}-\d{1}$
It works for the pattern but I need to validate that all numbers are not the same even after /separated by the hyphen (-).
Example:
0000-0 not allowed (because of all are same digits)
0000-1 allowed
1111-1 not allowed (because of all are same digits)
1234-2 allowed
TheFourthBird's answer surely works that uses a negative lookahead. Here is another variant of this regex that might be slightly faster:
^(\d)(?!\1{3}-\1$)\d{3}-\d$
RegEx Demo
Explanation:
^(\d) matches and captures first digit after start in group #1
(?!\1{3}-\1$) is a negative lookahead that will fail the match if we have 3 repetitions and a hyphen and another repeat of 1st digit.
You could exclude only - or the same digit only to the right till the end of the string:
^(\d)(?!(?:\1|-)*$)\d{3}-\d$
^ Start of string
(\d) Capture group 1, match a digit
(?! Negative lookahead, assert what is to the right is not
(?:\1|-)*$ Optionally repeat either the backrefernce to what is already captured or - till the end of the string
) Close the non capture group
\d{3}-\d Match 3 digits - and a digit
$ End of string
Regex demo
If you don't want to match double -- or an - at the end of the string and match optional repetitions:
^(\d)(?!(?:\1|-)*$)\d*(?:-\d+)*$
Explanation
^ Start of string
(\d) Capture a single digits in group 1
(?!(?:\1|-)*$) Negative lookahead, assert not only - and the same digit till the end of the string
\d* Match optional digits
(?:-\d+)* Optionally repeat matching - and 1+ digits
$ End of string
Regex demo
You'll need a back reference, for example:
^(\d){4}-\1$

Constructing regex in Java with variable number of certain characters in pattern

So a text file is given that should follow some a priori known format. I would like to check that such a text file indeed follows the format by reading each line in the text file and comparing to a regex. So, the first line in each text file is on the following format:
First character is "O" (capital o)
Characters 2-16 are numbers, with the exception of the 6:th character which is a blank space
Characters 17-30 is a decimal number, where character 28 is a decimal point
Characters 31-40 is an integer number
...
The specification continues, however I only need help with steps 3 and 4. For instance, a decimal number could be 1000.55, but in the text file it would be preceded by 7 blank spaces so that it fits the format. The same goes for step 4: if the number is 10, then this would be preceded by 8 blank spaces in the text file so that it fits.
How can I construct a regex that detects this pattern? Since the number of blank spaces may change, I am not sure. My idea was something like this:
String regex = "O[0-9]{4} [0-9]{10}[ ]*[0-9]*,[0-9]{2}"
The first letter is "O", followed by four digits, then a blank space, then 10 digits, then an unspecified number of blank spaces followed by an unspecified number of digits. Then finally decimal point and two digits. But this does not restrict the decimal number to only 14 characters! This is unfortunate, I do not think it will work.
You could match the first part for which you know the amount of occurrences.
For step 3 and 4 you could make use of positive lookaheads to assert the amount of occurrences.
In Java you could also use \h to match a horizintal whitespace char.
^O\d{4} \d{10}(?=[ \d]{11}\.) *\d*\.\d\d(?=[ \d]{10}) {0,9}\d+
In Java with the doubled backslashes:
String regex = "^O\\d{4} \\d{10}(?=[ \\d]{11}\\.) *\\d*\\.\\d\\d(?=[ \\d]{10}) {0,9}\\d+";
^O Match O at the start of the string
\d{4} \d{10} Match 4 digits, a space and 10 digits
(?=[ \d]{11}\.)
*\d*\.\d\d Match optional spaces . and 2 digits (If only .22 should also match)
(?=[ \d]{10}) Positive lookahead, assert 10 occurrences of either a space or digit to the right from the current position
{0,9}\d+ Match 0-9 spaces and 1+ digits
Regex demo
If the length of the string is a total of 40 characters, you can use a single lookahead (?=[ \d]{11}\.) because the string length is 40 characters.
^O(?=[\d .]{39}$)\d{4} \d{10}(?=[ \d]{11}\.) *\d*\.\d\d *\d+$
Regex demo

Regular Expression inner Digits check

I have the following regex but it fails (the inner digits with the points) :
([0-9]{1,3}\.?[0-9]{1,3}\.?[0-9]{1,3})
I want that it covers the following cases:
123 valid
123.4 valid
123.44 valid
123.445 valid
123.33.3 not ok (regex validates it as true)
123.3.3 not ok (regex validates it as true)
123.333.3 valid
123.333.34 valid
123.333.344 valid
Can you please help me?
You have multiple case, I would like to use | the or operator like this :
^([0-9]{1,3}|[0-9]{1,3}\.[0-9]{1,3}|[0-9]{1,3}\.[0-9]{3}\.[0-9]{1,3})$
^ ^ ^ ^
you can check the regex demo
details
The regex match three cases :
case 1
[0-9]{1,3}
this will match one or more digit
case 2
[0-9]{1,3}\.[0-9]{1,3}
this will match one or more digit followed by a dot then one or more digits
case 3
[0-9]{1,3}\.[0-9]{3}\.[0-9]{1,3}
this will match one or more digit followed by a dot then three digits then a dot then one or three digits
Note you can replace [0-9] with just \d your regex can be :
^(\d{1,3}|\d{1,3}\.\d{1,3}|\d{1,3}\.\d{3}\.\d{1,3})$
How about this one (demo at Regex101). It's pretty short and straightforward Regex:
(^\d{3}\.\d{3}\.\d{1,3}$)|(^\d{3}\.\d{1,3}$)|(^\d{3}$)
This recognizes three valid separate groups.
(^\d{3}\.\d{3}\.\d{1,3}$) as a group which must have 3 digits, a dot, 3 more digits, a dot and 1-3 digits.
(^\d{3}\.\d{1,3}$) as a group which must have 3 digits, a dot and 1-3 digits.
(^\d{3}$) as a group which must have 1-3 digits.
These groups split with the or (|) statement.
However, since you have tagged java, why don't let Java to take some responsibility and help Regex where isn't strong? I would rather match the format ((?:\d{1,3}\.?)+) and check programmatically whether the count of numbers is valid.
Use the following expression with .matches:
s.matches("\\d{1,3}(?:\\.\\d{3})?(?:\\.\\d{1,3})?")
See the regex demo
Details
^ - implicit, not necessary as the pattern is used in .matches that requires a full string match
\d{1,3} - 1 to 3 digits
(?:\.\d{3})? - an optional . and 3 digits
(?:\.\d{1,3})? - an optional sequence of . and 1 to 3 digits
$ - implicit, not necessary since the pattern is used in .matches that requires a full string match

Regular expression that accepts only two digit integer or a floating number

I am trying to validate a text field that accepts number like 10.99, 1.99, 1, 10, 21.
\d{0,2}\.\d{1,2}
Above expression is only passing values such as 10.99, 11.99,1.99, but I want something that would satisfy my requirement.
Try this:
^\d{1,2}(\.\d{1,2})?$
^ - Match the start of string
\d{1,2} - Must contains at least 1 digit at most 2 digits
(\.\d{1,2}) - When decimal points occur must have a . with at least 1 and at most 2 digits
? - can have zero to 1 times
$ - Match the end of string
Assuming you don't want to allow edge cases like 00, and want at least 1 and at most 2 decimal places after the point mark:
^(?!00)\d\d?(\.\d\d?)?$
This precludes a required digit before the decimal point, ie ".12" would not match (you would have to enter "0.12", which is best practice).
If you're using String#matches(), you can drop the leading/trailing ^ and $, because that method must to match the entire string to return true.
First \d{0,2} does not seem to fit your requirement as in that case it will be valid for no number as well. It will give you the correct output but logically it does not mean to check no number in your string so you can change it to \d{1,2}
Now, in regex ? is for making things optional, you can use it with individual expression like below:
\d{1,2}\.?\d{0,2}
or you can use it on the combined expression like below
\d{1,2}(\.\d{1,2})?
You can also refer below list for further queries:
abc… Letters
123… Digits
\d Any Digit
\D Any Non-digit character
. Any Character
\. Period
[abc] Only a, b, or c
[^abc] Not a, b, nor c
[a-z] Characters a to z
[0-9] Numbers 0 to 9
\w Any Alphanumeric character
\W Any Non-alphanumeric character
{m} m Repetitions
{m,n} m to n Repetitions
* Zero or more repetitions
+ One or more repetitions
? Optional character
\s Any Whitespace
\S Any Non-whitespace character
^…$ Starts and ends
(…) Capture Group
(a(bc)) Capture Sub-group
(.*) Capture all
(abc|def) Matches abc or def
Useful link : https://regexone.com/
Can you try using this :
(\d{1,2}\.\d{1,2})|(\d{1,2})
Here is a Demo, you can check also simple program
You have two parts or two groups one to check the float numbers #.#, #.##, ##.##, ##.# and the second group to check the integer #, ##, so we can use the or |, float|integer
I think patterns of this type are best handled with alteration:
/^\s*([-+]?[0-9]*\.[0-9]+([eE][-+]?[0-9]+)?)$ #float
| # or
^(\d{1,2})$ # 2 digit int/mx
Demo

Using Regex, is it possible to use an expression such as 'Followed by' or 'Preceded by'

I have the following expression where i want to extract an identifier that is 12 digits long:
([12]\d{3})(\d{6})(\d{2})
This works fine if the string is in the following format:
ABCD123456789101
123456789101
When it gets a string like the following, how does it know which 12 digits to match on:
ABCD1234567894837376383439434343232
1234567894837376383439434343232
In the above scenario, i dont want to select the twelve digits. So the answer i think is to only select the twelve digits, if those twelve digits are not preceded or proceeded by other digits. I tried this change:
[^0-9]([12]\d{3})(\d{6})(\d{2})[^0-9]
This basically says get me the 12 digits only if the characters before and after the 12 digits are non numeric. The problem i have is i am also getting those non-numeric characters as part of the match i.e.
ABCD123456789483X7376383439434343232 returns D123456789483X
Is there anyway of checking what the preceding and proceeding characters are but not include them in the match result? i.e. only match if the preceding and proceeding characters are non numeric but don't include those non-numeric characters in the match result.
You can use lookarounds:
(?<!\\d)([12]\d{3})(\d{6})(\d{2})(?!\\d)
Here:
(?<!\\d) is a negative lookbehind which means your pattern is not preceded by a digit
(?!\\d) is a negative lookahead which means your pattern is not followed by a digit
Read more about lookarounds

Categories

Resources