Generate strings larger than and lesser than - java

I need to test my method which is validate input Strings larger and lesser than.
I already achieved something like that:
//given
var generex = new Generex("[a-zA-Z]{3,100}");
patientDtoIn.setFirstName(generex.random());
This regex generate Strings larger than 3 and lesser than 100. Including this 2 numbers too.
Now I need the opposite. "Lesser than 3 and larger than 100" excluding those 2 numbers. Could someone help me with that?

You can use this regex:
^(?:[a-zA-Z]{1,2}|[a-zA-Z]{101,})$
Pattern explanation:
^ - match beginning of the string
(?:...) - non capturing group (used to group pattern)
[a-zA-Z]{1,2} - match pattern 1 or 2 times
| - alternation operator
[a-zA-Z]{101,} - match pattern 101 or more times
$ - match end of the string
Regex demo

Related

Regex to validate if a string has 2 consecutive letters(not 2 consecutive alphabet)

Conditions :
Contains only alphabet, hyphens and apostrophes.
Contains at least 2 consecutive letters
Does not start or end with space or hyphen
Contains minimum length of 2.
Valid: a-gm-k,ak,h-'kj,um'h-k
Invalid: a-h-j,
Tried ^([a-zA-Z'][a-zA-Z'-]*[a-zA-Z'])$
This is filing for the consecutive condition
Wrote \\b([a-zA-Z])\\1+\\b but this is failing if I give aa
Can somebody please advise how to write a single regex expression for above conditions?
A sequence of positive lookaheads (?=) needs to be applied:
(?=([-'A-Za-z]{2,}))(?=^[^- ].*[^- ]$)(?=.*[A-Za-z]{2,}.*)
where:
(?=([-'A-Za-z]{2,})) - contains only hyphen, apostrophe, or letters, minimum length of 2
(?=^[^- ].*[^- ]$) - does not start or end with - or space
(?=.*[A-Za-z]{2,}.*) - contains at least two consecutive letters
Online demo: Regexplanet
Online demo: regex101.com

Java 8 regex: a capturing group in a pattern doesn't match, yet the whole pattern does match

This is my first question. Nice to e-meet everyone.
I have created the following regex pattern in Java 8 (this is just a simplified example of what I actually have in my code - for the sake of clarity):
(?<!a)([0-9])\,([0-9])(?!a)|(?<!b)([0-9]) ([0-9])(?!b)|(?<!c)([0-9])([0-9])(?!c)
so in general it consists of three alternatives:
1st one matches two single digits separated with a comma, for example:
1,1
2,0
4,5
2nd one matches two single digits separated with a space, for example:
1 1
2 0
4 5
3rd one matches two single digits in a row, for example:
11
20
45
Each alternative uses lookarounds and their content has to be slightly different for each one of them - that's why I couldn't just put everything together like that:
([0-9])[, ]?([0-9])
Each of the matched digits is enclosed in a capturing group and now I have a second line to 'call out' these captured numbers like this:
(?<!n)($1 $2|$3 $4|$5 $6)(?!n)
So at the end I need to match a text that would have the same digits separated with single space and not surrounded by 'n'. So if any of the examples shown above would be matched by the pattern from the 1st line, the 2nd line pattern should match these:
1 1
2 0
4 5
11 11
22 00
44 55
And not any of these:
n1 1
2,0
45
asd asd asd
The problem is the following: it returns a match even if I do not have these captured digits in the tested text, but I do have space in it... So here I do not get match and that is correct:
aaaaaaaaa
bbbbbbbbb
aasdfasdf
but here I get a match on the following things (most apparently because there is a space/spaces):
abc abc
q w r t y
as df
Does anyone know if this is normal that despite the fact that the characters in capturing groups are not captured by the 1st line, the 'non capturing group' part (so a single space) will be matched and therefore the whole pattern returns match, as if a capturing group could be a zero-length match in the second line if nothing is captured by the first line? Thanks in advance for any comment on this.
Your regex matches whitespace because the resulting pattern for the 1,1 string is (?<!n)(1 1| | )(?!n), and it can match a space that is neither preceded nor followed with a space.
When a replacement backreference does not match any string in a .replaceAll/.replaceFirst it is assigned an empty string (it is assigned null when using .find() / .matches()), and thus you still get the blank alternatives in the resulting pattern.
You may leverage this functionality AND the fact that each alternative has exactly two capturing groups by concatenating replacement backreferences in the string replacement pattern, getting rid of the alternations altogether:
SEARCH: (?<!a)([0-9]),([0-9])(?!a)|(?<!b)([0-9]) ([0-9])(?!b)|(?<!c)([0-9])([0-9])(?!c)
REPLACE: (?<!n)($1 $2|$3 $4|$5 $6)(?!n)
Note how the backreferences are concatenated: all backreferences to odd groups come first, then all backreferences to even groups are placed in a no-alternative pattern.
See the regex demo.
Note that even if the number of groups is different across the alternatives you may just add "fake" empty groups to each of them, and this approach will still work.

minimum number in a string should be 1 regex validation?

I have a String which I need to match. Meaning it should only contains a number followed by space or just a number and minimum number should be 1 always. For ex:
3 1 2
1 p 3
6 3 2
0 3 2
First and third are valid string and all other are not.
I came up with below regex but I am not sure how can I check for minimum number in that string should be 1 always?
str.matches("(\\d|\\s)+")
Regex used from here
Just replace \\d with [1-9].
\\d is just a shorthand for the class [0-9].
This is a better regex though: ([1-9]\\s)*[1-9]$, as it takes care of double digit issues and won't allow space at the end.
Not everything can or should be solved with regular expressions.
You could use a simple expression like
str.matches("((\\d+)\\s)+")
or something alike to simply check that your input line contains only groups of digits followed by one or more spaces.
If that matches, you split along the spaces and for each group of digits you turn it into a number and validate against the valid range.
I have a gut feeling that regular expressions are actually not sufficient for the kind of validation you need.
If it should only contains a number followed by space or just a number and minimum number should be 1 and number can also be larger than 10 you might use:
^[1-9]\\d*(?: [1-9]\\d*)*$
Note that if you want to match a space only, instead of using \s which matches more you could just add a space in the pattern.
Explanation
^ Assert the start of the string
[1-9]\\d* Match a number from 1 up
(?: [1-9]\\d*)* Repeat a number from 1 up with a prepended space
$ Assert end of the string
Regex demo
Regex is part of the solution. But I don't think that regex alone can solve your problem.
This is my proposed solution:
private static boolean isValid(String str) {
Pattern pattern = Pattern.compile("[(\\d+)\\s]+");
Matcher matcher = pattern.matcher(str);
return matcher.matches() && Arrays.stream(Arrays.stream(matcher.group().split(" "))
.mapToInt(Integer::parseInt)
.toArray()).min().getAsInt() == 1;
}
Pay attention to the mathing type: matcher.matches() - to check match against the entire input. (don't use matcher.find() - because it will not reject invalid input such as "1 p 2")

Regular Expression that matches number with max 2 decimal places

I'm writing a simple code in java/android.
I want to create regex that matches:
0
123
123,1
123,44
and slice everything after second digit after comma.
My first idea is to do something like that:
^\d+(?(?=\,{1}$)|\,\d{1,2})
^ - from begin
\d+ match all digits
?=\,{1}$ and if you get comma at the end
do nothin
else grab two more digits after comma
but it doesn't match numbers without comma; and I don't understand what is wrong with the regex.
You may use
^(\d+(?:,\d{1,2})?).*
and replace with $1. See the regex demo.
Details:
^ - start of string
-(\d+(?:,\d{1,2})?) - Capturing group 1 matching:
\d+ - one or more digits
(?:,\d{1,2})? - an optional sequence of:
, - a comma
\d{1,2} - 1 or 2 digits
.* - the rest of the line that is matched and not captured, and thus will be removed.
basic regex : [0-9]+[, ]*[0-9]+
In case you want to specify min max length use:
[0-9]{1,3}[, ]*[0-9]{0,2}
Here:
,{1}
says: exactly ONE ","
Try:
,{0,1}
for example.

regex for optional characters

I am using the following regex:
^([W|w][P|p]|[0-9]){8}$
The above regex accepts wp1234567 (wp+7 digits) also. Whereas expected: WP+6digit or wp+6digit or only 8 digit
For example:
WP123456
wp126456
64535353
Note that [W|w] matches W, w and |, since | inside a character class loses its special meaning of an alternation operator. Also, by setting the grouping (...) around [W|w][P|p]|[0-9] you match 8 occurrences of *the whole sequences of WP or digits.
You should set the correct value in the limited quantifier and remove grouping and use alternation to allow either wp+6 digits or just 8 digits:
^(?:[Ww][Pp][0-9]{6}|[0-9]{8})$
See demo
The regex matches:
^ - start of string (not necessary if you check the whole string with String#matches())
(?:[Ww][Pp][0-9]{6}|[0-9]{8}) - 2 alternatives:
[Ww][Pp][0-9]{6} - W or w followed with P or p followed with 6 digits
| - or...
[0-9]{8} - exactly 8 digits
$ - end of string
Other scenarios (just in case):
If you need to match strings consisting of 7 or 8 digits, you need to replace {8} limited quantifier with {7,8}:
^(?:[Ww][Pp][0-9]{6}|[0-9]{7,8})$
And in case you do not want to match Wp123456 or wP123456, use one more alternation in the beginning:
^(?:(?:WP|wp)[0-9]{6}|[0-9]{8})$

Categories