简体   繁体   中英

What is the correct regex pattern for this?

I was solving this question from Hackerrank

https://www.hackerrank.com/contests/find-google/challenges/find-google/problem

and came up with this pattern "^[gG][o0O()\\[\\]{}][o0O()\\[\\]{}][gG][lLI][eE3]" But this is giving wrong answer for test case g()()GI3. Can anyone tell me the error? Also tell me if there is more efficient expression for this.

    import java.util.regex.*;
    import java.io.*;
    import java.util.*;
    class Main {

public static void main (String[] args) {
    Scanner s = new Scanner(System.in);
    String str = s.next();
    Pattern pattern = Pattern.compile("^[gG][o0O()\\[\\]{}][o0O()\\[\\]{}][gG][lLI][eE3]",Pattern.CASE_INSENSITIVE);
    Matcher matcher = pattern.matcher(str);
    if(matcher.matches())
    System.out.println("YES");
    else System.out.println("NO");
}}

The problem with the current regex is that [] , () and <> are put inside a character class that matches a single char inside it, but () , <> and [] char sequences consist of 2 chars.

You need to use a grouping construct with an alternation operator here to match o s.

You may use this pattern with Pattern.matches() :

Pattern pattern = Pattern.compile("[gG](?:[oO0]|\(\)|\[]|<>){2}[gG][LlI][eE3]");

See the regex demo

Details

  • [gG] - g or G
  • (?:[oO0]|\\(\\)|\\[]|<>){2} - two occurrences of
    • [o0] - o , O or 0
    • | - or
    • \\(\\) - a () substring
    • | - or
    • \\[] - a [] substring
    • | - or
    • <> - a <> substring
  • [gG] - g or G
  • [LlI] - l , L or I
  • [eE3] - e , E or 3 .

You can use this

You do not need to add both uppercase and lowercase of a letter when you use case insensitive flag.

g(?:o|0|<>|\[]){2}g[li][e3]
  • g - Matches g or G ( as case insensitive flag is on )
  • (?:o|0|<>|\\[]) - Matches o or 0 or <> or [] .
  • [li] - Matches L or l or I or i .
  • [e3] - Matches e or E or 3

Demo

I propose you this version of the regex string along with the code:

String string = bufferedReader.readLine();
String regex = "^[gG]([o0O]|\\(\\)|\\[\\]|\\{\\}|\\<\\>){2}[gG][lLI][eE3]";        
String result = Pattern.matches(regex, string) ? "True" : "False";
System.out.println(result);

Since it's a "one shot" search you can use the static method "matches" of the Pattern class. That is, desume the result directly from a one-time match against your regex.

The regex is mostly the same as the one you devised, but some points are worth noting.

It is dangerous (if not erroneous) using case insensitivity when your regex tries to pick up letters of differente case. If you want to do the matching the classic way, avoid using the flag of case insensitivity. (in this particular case it would match a "google" written with a lower case "i" in place of a "L", which would lead to false positives).

Since there is only one way to express the "o", it is better to group its definition in a single sub-expression and then use the quantifier " {2} " to say that you exactly want two instances of that subexpression to match.

You want to find two occurrences of EITHER

  • either a lower/upper case "o"
  • a zero
  • a pair of normal/square/curly/angular parentheses

Last but not least, if you are looking for simple, square, curly or angular braces, you must escape them because those are special characters in a regexp. Moreover, you must escape them the java way, using a double blackslash.

Here is the full code:

    public static void main(String[] args) throws IOException {
       BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in));

       String string = bufferedReader.readLine();
       String regex = "^[gG]([o0O]|\\(\\)|\\[\\]|\\{\\}|\\<\\>){2}[gG][lLI][eE3]";        
       String result = Pattern.matches(regex, string) ? "True" : "False";
       System.out.println(result);

       bufferedReader.close();
}

It prints "True" when fed with the input "g()()GI3"

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM