Reputation: 2430
I have a text field which will contain strings "Yes" or "No"
I need a regular expression which will allow only one of those strings. ie The text should contain only one string, either "Yes" or "No". The text should not contain both "Yes" and "No".
(^((?!.*No).*Yes.*)$)|(^((?!.*Yes).*No.*)$)
Eg:
Yes, correct = allow this
No, Incorrect = allow this
Yes, correct- No Incorrect = Don't allow this
I have tried this. But this is allowing both. any help appreciated.
Upvotes: 1
Views: 664
Reputation: 168061
You can use the pattern:
^((?:(?!No).)*Yes(?:(?!No).)*|(?:(?!Yes).)*No(?:(?!Yes).)*)$
Like this:
import java.util.regex.Pattern;
public class RegexpYesNo {
static Pattern YesOrNoRegex = Pattern.compile( "^((?:(?!No).)*Yes(?:(?!No).)*|(?:(?!Yes).)*No(?:(?!Yes).)*)$" );
public static boolean containsYesOrNo(
final String input
){
return YesOrNoRegex.matcher( input ).matches();
}
public static void main( final String[] args ){
final String[] tests = {
"Yes, correct = allow this",
"No, Incorrect = allow this",
"Yes, correct- No Incorrect = Don't allow this"
};
for ( final String test : tests )
System.out.println( containsYesOrNo( test ) );
}
}
However, a simpler way to do it is not to use a regular expression:
public static boolean containsYesOrNo(
final String input
){
return input.contains( "Yes" ) != input.contains( "No" );
}
Upvotes: 1
Reputation: 36304
This stupid long regex will do it for you :P
public static void main(String[] args) throws IOException, InterruptedException {
String s = "Yes, correct- No Incorrect";
System.out.println(s.matches("(?=.*(?<![a-zA-Z])Yes(?![a-zA-Z]))(?=.*(?<![a-zA-Z])No(?![a-zA-Z])).*"));
}
O/P :
true
PS: Use ?i
to make the regex case-insensitive.
The above code check for Yes and No and ensure that they are not part of a different word (like Yesterday or Nobody)
Upvotes: 1
Reputation: 626936
If you really need to do it with a regex, use
(?i)^(?!.*(?:\byes\b.*\bno\b|\bno\b.*\byes\b)).*\b(?:yes|no)\b.*
See the regex demo
In Java:
String ptrn = "(?i)^(?!.*(?:\\byes\\b.*\\bno\\b|\\bno\\b.*\\byes\\b)).*\\b(?:yes|no)\\b.*";
Add a DOTALL modifier if your string contains newline symbols.
Explanation:
(?i)
- enabling the case insensitive mode^
- start of string(?!.*(?:\byes\b.*\bno\b|\bno\b.*\byes\b))
- a negative lookahead failing the match if there are yes
or no
or no
and yes
as whole words (due to word boundary \b
) later in the string.*
- matches zero or more characters other than a newline (without a DOTALL modifier(\b(?:yes|no)\b
- either a yes
or a no
.*
- zero or more characters other than a newline (without a DOTALL modifier)Upvotes: 0