Pattern Syntax Checker | HackerRank Solution

Pattern Syntax Checker | HackerRank Solution

Pattern Syntax Checker is a HackerRank Java problem that looks like it needs a parser, but it does not. You are given some regex patterns and must say which ones are written correctly. Instead of checking brackets and quantifiers yourself, you let Java's own regex engine try to compile the pattern and you watch whether it complains.

The real topic here is exception handling. You call a method that throws one specific exception when input is bad, you catch exactly that error, and you turn it into a clean answer. That "try it and catch the failure" style is common in real code too, for example when parsing user-entered dates or numbers.

Problem

You get several regular expressions. For each one, decide whether its syntax is valid. Here "valid" has a precise meaning: a pattern is valid if Pattern.compile accepts it without throwing an error.

Input: the first line has an integer N, the number of test cases. Each of the next N lines holds one pattern, which can contain any printable characters (including spaces).

Output: for each pattern print Valid or Invalid on its own line, without quotes.

Input:
3
([A-Z])(.+)
[AZ[a-z](a-z)
batcatpat(nat

Output:
Valid
Invalid
Invalid

Approach

The definition in the problem tells you the method. Pattern.compile(String regex) turns a regex string into a compiled pattern. If the string breaks regex grammar, it throws PatternSyntaxException. So:

  1. Read N. Use nextLine() and parse it, so the scanner moves past the end of that first line.
  2. For each test case, read the full line with nextLine(). Do not use next(), because a pattern can contain spaces and next() stops at the first space.
  3. Call Pattern.compile(line) inside a try. If it returns, print Valid.
  4. Catch PatternSyntaxException and print Invalid.

Dry run on the sample:

  • ([A-Z])(.+) has two balanced groups, a character class and a + after a dot. It compiles, so Valid.
  • [AZ[a-z](a-z) opens a character class with [. Inside it, [a-z] is a nested class (Java allows that), but the outer [ is never closed. Compile fails with "Unclosed character class", so Invalid.
  • batcatpat(nat opens a group with ( and never closes it. Compile fails with "Unclosed group", so Invalid.

A nice side effect of catching the exception: e.getDescription() and e.getIndex() tell you what went wrong and where. You do not need them here, but they are handy when you build a regex tester or show errors to users.

Solution in Java

import java.util.Scanner;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public class Solution {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int testCases = Integer.parseInt(in.nextLine().trim());

        for (int t = 0; t < testCases; t++) {
            String pattern = in.nextLine();   // read the whole line, spaces included
            try {
                Pattern.compile(pattern);     // throws if the syntax is broken
                System.out.println("Valid");
            } catch (PatternSyntaxException e) {
                System.out.println("Invalid");
            }
        }
        in.close();
    }
}

This follows the same idea as the old solution on this page, which was fine. I added trim() when reading N, so a stray space after the number does not crash Integer.parseInt, and used a plain counted for loop.

Why catch PatternSyntaxException and not just Exception? Because it says exactly what you expect to go wrong. If some other bug happens (say the input runs out), you want to see that error, not have it silently printed as "Invalid".

Edge cases I ran:

  • *abc is Invalid. A quantifier needs something before it to repeat ("Dangling meta character").
  • a{2,1} is Invalid ("Illegal repetition range"), because the minimum is bigger than the maximum.
  • hello world is Valid. The space is just a literal character, which is why reading the whole line matters.
  • \d+ is Valid.

Output

Valid
Invalid
Invalid

Complexity

Time: O(L) per pattern to compile it, where L is the pattern length, so O(total input size) overall.

Space: O(L) for the compiled pattern of the current line, which is thrown away after each test case.

Common mistakes

  • Reading N with nextInt() and then calling nextLine(). The first nextLine() returns the empty rest of line one, so every answer shifts by one line.
  • Reading patterns with next(), which breaks patterns that contain spaces.
  • Trying to validate by counting brackets yourself. Regex syntax has escapes, nested classes and quantifier rules, and you will miss cases that Pattern.compile already knows.
  • Forgetting the import for java.util.regex.PatternSyntaxException, or catching a different exception type that compile never throws.

Continue with Java Regex (IP address validation), or go back to Java String Tokens.

Tip: try to solve the problem yourself before reading the solution. Use the code as a reference to check your approach, and make sure you understand why it works.

More HackerRank solutions All coding problems MCQ practice

Comments

Answered 0/0Correct 0