Regex not required [duplicate] - java

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")

Related

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.

Why #PathVariable trims the data containing #? [duplicate]

This question already has an answer here:
How to escape hash character in URL
(1 answer)
Closed 2 years ago.
I have a URI mapping in my custom controller given below :
http://localhost:8080/abc/{id}
Now, for normal values in id, it's not creating any problem.
When id contains a #, the content gets trimmed.
For example: for id = 123#qqq, then #PathVariable makes it 123
How to resolve this issue ?
You basically have 2 options:
1) Keep id as Path Variable and escape the #
As already mentioned in the comments # is a special character in URIs normally reserved to refer anchor positions on the webpage. If you want to use it as a path variable you will have to escape it:
http://localhost:8080/abc/123%23qqq
Will yield your desired id = 123#qqq
2) Use a Request Parameter instead
This seems to to me the cleaner solution. If you have to have the # as part of your id, you should propably just encode it as a String in a request parameter:
public void fooBar(#Requestparam String id) {
// do stuff
}
This way you won't have to worry about URI encodings since your # character will be interpreted as a String.

Is quantifiers are required in all the Regex expressions?

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.

Java regex: How to match a string if its not consisting a list of certain top level domains [duplicate]

This question already has answers here:
Regular expression to match a line that doesn't contain a word
(34 answers)
Closed 5 years ago.
im trying to build a regex where i try to filter urls and only those who are not given in my regex will result in a match.
If there is no test1.com or test2.com in the url it should result in a match.
The top level domains i want not to result in a match (test1.com and test2.com) are using always the https protocol, can contain subdomains and having paths after the top level domain ".com".
Last try was the following but still doesnt work...
https?://([a-z0-9]+[.])((test1)|(test2))[.](com)/.*
Result on regexplanet:
https://abc.test1.com/test.htm
==> MATCH
www.google.com
==> NO MATCH
https://123.test2.com/test.html
==> MATCH
https://test2.com/test.html
==> NO MATCH
Ho do i need to write the regex that everything which has not the test1.com and test2.com domain in its string will give a match?
This pattern should work:
^((?!test1\\.com|test2\\.com).)*$
Try out:
System.out.println(Pattern.matches("^((?!test1\\.com|test2\\.com).)*$", "https://abc.test1.com/test.htm"));
System.out.println(Pattern.matches("^((?!test1\\.com|test2\\.com).)*$", "www.google.com"));
System.out.println(Pattern.matches("^((?!test1\\.com|test2\\.com).)*$", "https://123.test2.com/test.html"));
System.out.println(Pattern.matches("^((?!test1\\.com|test2\\.com).)*$", "https://test2.com/test.html"));
Results:
false
true
false
false

How to separate a string into multiple lines based on a separator but not if it is preceded by '?' [duplicate]

This question already has answers here:
Regex lookahead, lookbehind and atomic groups
(5 answers)
Closed 6 years ago.
I am trying to separate a string into multiple lines based on separator ' but if there's a ? character before ' I want the data to remain in the same line.
Initial String:
HJK'ABCP?'QR2'SER'
I am able to print the lines like:
HJK'
ABCP?'
QR2'
SER'
But I want the output as:
HJK'
ABCP?'QR2'
SER'
You need a negative lookbehind (http://www.regular-expressions.info/lookaround.html) :
String str = "HJK'ABCP?'QR2'SER'";
System.out.println(str);
System.out.println("---------------");
System.out.println(str.replaceAll("'", "'\r\n"));
System.out.println("---------------");
System.out.println(str.replaceAll("(?<!\\?)'", "'\r\n"));
It returns :
HJK'ABCP?'QR2'SER'
---------------
HJK'
ABCP?'
QR2'
SER'
---------------
HJK'
ABCP?'QR2'
SER'
Use this regex (?<!\?)' in split funtion
String s="HJK'ABCP?'QR2'SER'";
System.out.println(s.replaceAll("(?<!\\?)'","\r\n"));

Categories