Is quantifiers are required in all the Regex expressions? - java

I am building a Spring Boot application where input parameters are validated using java.validation.*. I want to check my input parameters for alphabetical characters, numbers and hyphen.
public class Foo {
#NotNull #NotEmpty
#Pattern(regexp = "^[a-zA-Z0-9-]")
private String subscriberType;
#NotNull #NotEmpty
#Size(min = 32, max = 43)
#Pattern(regexp = "^[a-zA-Z0-9-]")
private String caseId;
......
I am using regex as below.
#Pattern(regexp = "^[a-zA-Z]")
If I use above and give input parameters as below,
{
"subscriberType":"prepaid",
"caseId":"5408899645efabf60844de9077372571"
}
I get my validation failed.
Resolving exception from handler [public org.springframework.http.ResponseEntity<java.lang.Object> my.org.presentation.NumberRecycleController.numberRecycle(java.util.Optional<java.lang.String>,my.org.domain.request.NumberRecycleReqDto)
throws java.lang.Exception]: org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument at index 1 in method:
public org.springframework.http.ResponseEntity<java.lang.Object> my.org.presentation.NumberRecycleController.numberRecycle(java.util.Optional<java.lang.String>,my.org.domain.request.NumberRecycleReqDto)
throws java.lang.Exception, with 2 error(s): [Field error in object 'numberRecycleReqDto' on field 'subscriberType': rejected value [prepaid]; codes [Pattern.numberRecycleReqDto.subscriberType,
Pattern.subscriberType,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable:
codes [numberRecycleReqDto.subscriberType,subscriberType]; arguments []; default message [subscriberType],[Ljavax.validation.constraints.Pattern$Flag;#5dcb2ea8,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute#3de9c7b1];
default message [must match "^[a-zA-Z0-9]"]] [Field error in object
'numberRecycleReqDto' on field 'caseId': rejected value [35408899645efabf60844de907737257]; codes [Pattern.numberRecycleReqDto.caseId,Pattern.caseId,Pattern.java.lang.String,Pattern];
arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [numberRecycleReqDto.caseId,caseId]; arguments [];
default message [caseId],[Ljavax.validation.constraints.Pattern$Flag;#5dcb2ea8,org.springframework.validation.beanvalidation.SpringValidatorAdapter$ResolvableAttribute#61637994]; default message [must match "^[a-zA-Z0-9-]"]]
I have gone through some similar questions and found a solution. I can get my validation success if I use my regex as below.
#Pattern(regexp = "^[a-zA-Z0-9-]+"
or
#Pattern(regexp = "^[a-zA-Z0-9-]{1,}"
Can you please explain what actually happens here? I know that quantifiers are looking for given number of matches. In my case 1 or more matches which fall into given pattern.
My question is, giving a quantifier is always required or what? What is the reason for the failure of my initial regex pattern?

The pattern must match the whole string. A character class matches only one character. If the string may contain more than one character, you need the quantifier.
Btw. the ^ at the beginning of the regular expression is redundant. The pattern always must match the whole string.

Related

Javax Pattern annotation failing for correct values

I need to use validation where input value should end with "Type" So I came up with Type$ regex, but it is failing for correct values. Here is how I am using this in Pattern annotation in my code
#Pattern(regexp = REGISTRY_CONFIG_TYPE_FORMAT,message = REGISTRY_CONFIG_TYPE_ERROR)
#ApiModelProperty(name = "registryConfigType", dataType = "String", value = "OccasionType", example = "OccasionType", required = true)
private String registryConfigType;
the constant value
REGISTRY_CONFIG_TYPE_FORMAT = "Type$"
when I am passing value like : OccasionType, I am getting the error message. But on regex101 it's working fine. Not sure where is the problem.
following is the error log which I am getting
Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public com.macys.registry.dataobject.v1.response.RegistryAppResponse<java.lang.Object> com.macys.registry.controller.RegistryConfigController.updateConfig(com.macys.registry.dataobject.v1.request.UpdateRegistryConfigRequest): [Field error in object 'updateRegistryConfigRequest' on field 'registryConfigType': rejected value [OccasionType]; codes [Pattern.updateRegistryConfigRequest.registryConfigType,Pattern.registryConfigType,Pattern.java.lang.String,Pattern]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [updateRegistryConfigRequest.registryConfigType,registryConfigType]; arguments []; default message [registryConfigType],[Ljavax.validation.constraints.Pattern$Flag;#20999237,Type$]; default message [Registry Config Type Should Not Be Null And Should End With [Type]]] ]
Try this for your case
REGISTRY_CONFIG_TYPE_FORMAT= ".*Type$";
It may not be 100% clear from the javadoc, but the regexp must match. In other words, the entire input must be captured by the regexp. A simple fix: .*Type. Note that the $ is unnecessary, as that's already implied by the matching.
Your regex would be valid if find where used instead of match.
Try changing you constant to:
REGISTRY_CONFIG_TYPE_FORMAT = "\\w*Type\\b";
From RegExr:
\w Word. Matches any word character (alphanumeric & underscore).
* Quantifier. Match 0 or more of the preceding token.
T Character. Matches a "T" character (char code 84). Case sensitive.
y Character. Matches a "y" character (char code 84). Case sensitive.
p Character. Matches a "p" character (char code 84). Case sensitive.
e Character. Matches a "e" character (char code 84). Case sensitive.
\b Word boundary. Matches a word boundary position between a word character and non-word character or position (start / end of string).
Hope this will help.

Java validation annotation #Pattern with regexp of \\\\ doesn't work properly

I need to do a validation for one of the request fields. I use annotation #Pattern for this.
#Size(min = 3, max = 1000)
#Pattern(regexp = "[0-9A-Za-z\\\\/]+")
private String name;
That is, I must be able to enter the latin letters, numbers, slash and backslash. With this pattern, when I trying to write something like name/\ (looks like "name/\\" in Postman) I get an error
Unexpected internal error near index 6\r\nname/\\
UPDATE:
I did pattern [////]+ and it works! But when I added the alphabet again, the problem came back. I noticed that the stack trace looks different than it does for validation. The error occurs on the following line:
Pattern pattern = Pattern.compile(name, Pattern.CASE_INSENSITIVE);
I use this to check if the same name exists in the MongoDB.

regular expression with cucumber doesn't match the string giving error but would match the same string if the test is written more than once

I'm writing in java and using cucumber with eclipse to search for an IP-like string with the following requirements
should accept four-digit sequences separated by periods
where a digit sequence is defined as follows: Any single digit, Any two-digit characters if the first character is non-zero, A one followed by a zero, one, or two followed by any digit
by writing the appropriate regular expression in the Stepdefs.java file, this is what I wrote
#When("^test_ip_address ((?:(\\d)|(1[0-2]\\d)|([1-9]\\d))\\.){3}(?:(\\d)|([1-9]\\d)|(1[0-2]\\d))$")
public void test_ip_address(String arg1) throws Throwable {
System.out.println("test_ip_address true for: " + arg1);
}
now when I write tests (in Gherkin language) for this method in the Test.feature file the first test always fail, the tests (which should all pass )
When test_ip_address 1.2.3.4
When test_ip_address 123.34.76.109
When test_ip_address 123.34.76.109
When test_ip_address 105.22.33.44
it's not a matter of value like when I re-order those tests it's always the first one only that fails even if I used the exact same value in another test it passes ! this is the error I get
cucumber.runtime.CucumberException: Arity mismatch: Step Definition 'skeleton.Stepdefs.test_ip_address(String) in file:(file path..)' with pattern [^test_ip_address ((?:(\d)|(1[0-2]\d)|([1-9]\d))\.){3}(?:(\d)|([1-9]\d)|(1[0-2]\d))$] is declared with 1 parameters. However, the gherkin step has 7 arguments [3., 3, null, null, 4, null, null]
i have searched about the errors and it's thrown when the number of arguments in the test is not the same as in the method,even when i'm using (?:) to pass the string as one argument, I don't know where those 7 arguments came from ! nor the cause of error
cucumber.runtime.CucumberException: Arity mismatch: Step Definition 'skeleton.Stepdefs.test_ip_address(String) in file:(file path..)' with pattern [^test_ip_address ((?:(\d)|(1[0-2]\d)|([1-9]\d))\.){3}(?:(\d)|([1-9]\d)|(1[0-2]\d))$] is declared with 1 parameters. However, the gherkin step has 7 arguments [3., 3, null, null, 4, null, null]
This error is due to the regular expression is having 7 groups. which capture 7 parameters. And the method
public void test_ip_address(String arg1) throws Throwable
only declares 1 parameter (arg1).
To capture only one parameter, use non capturing group to avoid capturing unnecessary group as method argument.
The expression should look like this:
#When("^test_ip_address ((?:(?:(?:\\d)|(?:1[0-2]\\d)|(?:[1-9]\\d))\\.){3}(?:(?:\\d)|(?:[1-9]\\d)|(?:1[0-2]\\d)))$")
The following regex expression should validate all IPv4 addresses:
String zeroTo255 = "(\\d{1,2}|(0|1)\\" + "d{2}|2[0-4]\\d|25[0-5])";
String regex = zeroTo255 + "\\." + zeroTo255 + "\\." + zeroTo255 + "\\." + zeroTo255;
Use this regex variable instead. Hopefully this answered your question :)
We dont need edit regular expressions because that is converted from our feature file as step definition file

Regex not required [duplicate]

This question already has answers here:
Regular expression which matches a pattern, or is an empty string
(5 answers)
Closed 3 years ago.
I am trying to develop a simple REGEX in Java with pattern like that :
#Pattern(regexp = "[a-zA-Z]{2}[0-9]{1}[2-8]{1}" , message = "The format is invalid")
but this message is still displayed when the field is empty,
so i want to show this message only when the field is not empty (i want that the field is will be not required).
Thank you.
Try using the following regex, which matches both your expected string and empty string:
[a-zA-Z]{2}[0-9]{1}[2-8]{1}|^$
Java code:
#Pattern(regexp = "[a-zA-Z]{2}[0-9]{1}[2-8]{1}|^$", message = "The format is invalid")
You could make your whole pattern optional using a non capturing group (?:...)?to match either an empty string or the whole pattern.
Note that you can omit the {1} part.
^(?:[a-zA-Z]{2}[0-9][2-8])?$
Regex demo
#Pattern(regexp = "^(?:[a-zA-Z]{2}[0-9][2-8])?$" , message = "The format is invalid")

Spring Boot - custom validation message with annotation parameters

I want to create my custom validation messages with Spring Boot/MVC Validation.
I found following setup working:
public class RegisterCredentials {
#NotEmpty
#NotNull
#Size(min=3, max=15)
private String username;
...
}
messages.properties:
NotEmpty.registerCredentials.username = Username field cannot be empty.
NotNull.registerCredentials.username = Username field cannot be empty.
Size.registerCredentials.username = Username length must be between 3 and 15 characters.
After that I wanted to replace fixed values min=3 and max=15 with attributes. I tried like that, but it didn't worked (it works in #Size(message="..") annotation):
Size.registerCredentials.username = Username length must be between {min} and {max} characters.
Then I found following code working..:
Size.registerCredentials.username = Username length must be between {1} and {2} characters.
Well.. almost, because it produces following message:
Username length must be between 15 and 3 characters.
Replacing order of these {1} and {2} solves the problem, however it produces confusing code in futher analyze.
Is there a solution to solve this problem with clean code?

Categories