Regex exactly n OR m times
There is no single quantifier that means "exactly m or n times". The way you are doing it is fine.
An alternative is:
X{m}(X{k})?
where m < n
and k
is the value of n-m
.
Regex group match exactly n times
Your first regex is incorrect because it asserts that id
is present after the first three items.
Your second regex matches the string incorrectly because .*
matches hyphens as well.
You should use this regex:
/^(?:[^-]+-){2}id/
Here is a regex demo!
And if you feel a need to anchor a regex to the end, use /^(?:[^-]*-){2}id.*$/
!
As mentioned by Tim Pietzcker, consider asserting id
at the end of the item:
/^(?:[^-]+-){2}id(?![^-])/
Here is an UPDATED regex demo!
RegExp Quantifier to Match Pattern Exactly n or m Times Instead of n to m Times
You can use negative lookbehind/lookahead to accomplish this:
Here's one possible way to accomplish what you're trying to do.
/(?<!\d)(\d{2}|\d{4})(?!\d)/
This says - find a 2 or 4 digit number that is not preceded or followed by another number. This differs from the answer above in that it will match ALL 2 and 4 digit numbers including those that are not surrounded by spaces such as the "12" in the string "abc12def".
Which way you choose will depend on what in particular you are looking for.
Regex to match at least n times but not more than m times
Although it's often written as {min,max}
in tutorials and references, the enumerated quantifier does not mean not more than max
. If it sees three hyphens, -{1,3}
will consume all three, but it doesn't care what the next character is (if there is one). It's just like all other quantifiers in this regard: it consumes as much as it can, then it hands control to the next part of the regex.
That's why the other responders suggested using an end anchor ($
). If you can't use an anchor, or don't want to, you can use a negative lookahead instead:
/^%\*-{1,3}(?!-)/
How does {m}{n} (exactly n times twice) work?
When I input your regex in RegexBuddy using the Java regex syntax, it displays following message
Quantifiers must be preceded by a token that can be repeated «{2}»
Changing the regex to explicitly use a grouping ^(\d{1}){2}
solves that error and works as you expect.
I assume that the java regex engine simply neglects the error/expression and works with what has been compiled so far.
Edit
The reference to the IEEE-Standard in @piet.t's answer seems to support that assumption.
Edit 2 (kudos to @fncomp)
For completeness, one would typically use (?:)
to avoid capturing the group. The complete regex then becomes ^(?:\d{1}){2}
Regex to match exactly n occurrences of letters and m occurrences of digits
You can use
^(?=[^A-Z]*[A-Z][^A-Z]*$)(?=[^a-z]*[a-z][^a-z]*$)(?=(?:\D*\d){6}\D*$)[a-zA-Z0-9]{8}$
See the regex demo (a bit modified due to the multiline input). In Java, do not forget to use double backslashes (e.g. \\d
to match a digit).
Here is a breakdown:
^
- start of string (assuming no multiline flag is to be used)(?=[^A-Z]*[A-Z][^A-Z]*$)
- check if there is only 1 uppercase letter (use\p{Lu}
to match any Unicode uppercase letter and\P{Lu}
to match any character other than that)(?=[^a-z]*[a-z][^a-z]*$)
- similar check if there is only 1 lowercase letter (alternatively, use\p{Ll}
and\P{Ll}
to match Unicode letters)(?=(?:\D*\d){6}\D*$)
- check if there are six digits in a string (=from the beginning of the string, there can be 0 or more non-digit symbols (\D
matches any character but a digit, you may also replace it with[^0-9]
), then followed by a digit (\d
) and then followed by 0 or more non-digit characters (\D*
) up to the end of string ($
)) and then[a-zA-Z0-9]{8}
- match exactly 8 alphanumeric characters.$
- end of string.
Following the logic, we can even reduce this to just
^(?=[^a-z]*[a-z][^a-z]*$)(?=(?:\D*\d){6}\D*$)[a-zA-Z0-9]{8}$
One condition can be removed as we only allow lower- and uppercase letters and digits with [a-zA-Z0-9]
, and when we apply 2 conditions the 3rd one is automatically performed when matching the string (one character must be an uppercase in this case).
When using it with Java matches()
method, there is no need to use ^
and $
anchors at the start and end of the pattern, but you still need it in the lookaheads:
String s = "K82v6686";
String rx = "(?=[^a-z]*[a-z][^a-z]*$)" + // 1 lowercase letter check
"(?=(?:\\D*\\d){6}\\D*$)" + // 6 digits check
"[a-zA-Z0-9]{8}"; // matching 8 alphanum chars exactly
if (s.matches(rx)) {
System.out.println("Valid");
}
Regex, That Matches No more Than n Occurrences
You can specify a character, or you can generalize it to all characters.
Also, not sure if you're trying to test or match the whole string, but assume
it's the whole string.
Generalized
^(?:(\w)(?!\1{2})|\W)+$
Explained
^ # Beginning of string
(?: # Cluster
( \w ) # (1), a word character
(?! \1{2} ) # Not 2 more of same in a sequence
| # or,
\W # Not a word character
)+ # End Cluster, 1 to many times
$ # End of string
You could substitute specific characters instead of \w
and \W
by replacing what you want.
Example for character a
it would be a
and [^a]
.
^(?:(a)(?!\1{2})|[^a])+$
or more than one like [abc]
and [^abc]
^(?:([abc])(?!\1{2})|[^abc])+$
Regex matching exactly 3 or exactly 7 characters
To match either 3 or 7 characters, you could first match 3 characters and optionally 4 more;
^[^*]{3}(?:[^*]{4})?\*(.*)
[^*]{3}
matches 3 characters that aren't an asterisk
(?:[^*]{4})?
optionally matches 4 characters that are not an asterisk. ?:
makes it a non capturing group since you're not interested in the content.
Regex101 to test with.
Related Topics
How to Stop Java Process Gracefully
Growing Resident Memory Usage (Rss) of Java Process
Downloading Java Jdk on Linux Via Wget Is Shown License Page Instead
Classpath Does Not Work Under Linux
React on Global Hotkey in a Java Program on Windows/Linux/Mac
Java Processbuilder: Resultant Process Hangs
Java Can't Connect to X11 Window Server Using 'Localhost:10.0' as the Value of the Display Variable
Will System.Currenttimemillis Always Return a Value ≫= Previous Calls
Technically What Is the Main Difference Between Oracle Jdk and Openjdk
Gradle Finds Wrong Java_Home Even Though It's Correctly Set
Do Line Endings Differ Between Windows and Linux
Javafx on Linux Is Showing a "Graphics Device Initialization Failed For: Es2, Sw"
How to Stop Repeated Keypressed()/Keyreleased() Events in Swing
Relation Between Memory Host and Memory Arguments Xms and Xmx from Java