Dipu H
Dipu H

Reputation: 2430

Regular Expression to allow only one pattern among the two

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

Answers (3)

MT0
MT0

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

TheLostMind
TheLostMind

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

Wiktor Stribiżew
Wiktor Stribiżew

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

Related Questions