ZetCode

Java PatternSyntaxException Class

Last modified: April 20, 2025

The java.util.regex.PatternSyntaxException is an unchecked exception thrown when a regular expression pattern has invalid syntax. It extends IllegalArgumentException and provides detailed error information.

This exception occurs during pattern compilation when the regex syntax is incorrect. It includes methods to get the error description, the erroneous pattern, and the index where the error occurred. Understanding this exception helps debug regex issues.

PatternSyntaxException Overview

PatternSyntaxException provides information about syntax errors in regex patterns. The exception message includes the error description, the pattern, and a visual indicator of the error position. This helps quickly identify and fix syntax issues.

Key methods include getDescription, getPattern, and getIndex. These provide programmatic access to error details. The exception is thrown by Pattern.compile and related methods.

Basic PatternSyntaxException Example

This example demonstrates catching a PatternSyntaxException when compiling an invalid regex pattern. The pattern contains an unclosed character class, which is invalid syntax. We'll show how to extract error details from the exception.

BasicSyntaxError.java
package com.zetcode;

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

public class BasicSyntaxError {

    public static void main(String[] args) {
        
        try {
            // Invalid pattern with unclosed character class
            Pattern.compile("[a-z");
            
        } catch (PatternSyntaxException e) {
            System.out.println("Error Description: " + e.getDescription());
            System.out.println("Error Index: " + e.getIndex());
            System.out.println("Erroneous Pattern: " + e.getPattern());
            
            // The exception message includes all details
            System.out.println("\nFull error message:");
            System.out.println(e.getMessage());
        }
    }
}

In this example, we attempt to compile an invalid pattern "[a-z" (missing closing bracket). The PatternSyntaxException provides detailed information about the error. The getDescription method returns a human-readable error message.

The getIndex method indicates where in the pattern the error occurred. getPattern returns the erroneous pattern. The exception's getMessage combines all this information in a formatted string.

Handling Multiple Syntax Errors

This example shows how different types of syntax errors trigger PatternSyntaxException. We'll test several invalid patterns and display their error details. Each error type produces a different description.

MultipleSyntaxErrors.java
package com.zetcode;

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

public class MultipleSyntaxErrors {

    public static void main(String[] args) {
        
        String[] invalidPatterns = {
            "[a-z",       // Unclosed character class
            "a{2,1}",     // Invalid quantifier range
            "(?<!name)",  // Invalid lookbehind
            "\\",         // Trailing backslash
            "*abc"        // Dangling quantifier
        };
        
        for (String pattern : invalidPatterns) {
            try {
                Pattern.compile(pattern);
            } catch (PatternSyntaxException e) {
                System.out.println("Pattern: " + pattern);
                System.out.println("Error: " + e.getDescription());
                System.out.println("Index: " + e.getIndex() + "\n");
            }
        }
    }
}

This code tests five different invalid patterns. Each triggers a PatternSyntaxException with specific error details. The output shows how each error type is reported differently. The index indicates where the parser detected the problem.

Note how each syntax error produces a distinct description. The descriptions help identify exactly what's wrong with the pattern. This is valuable for debugging complex regular expressions.

Validating Regex Patterns

This example demonstrates a utility method to validate regex patterns before use. It catches PatternSyntaxException and returns validation results. This is useful in applications where users can input custom regex patterns.

RegexValidator.java
package com.zetcode;

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

public class RegexValidator {

    public static void main(String[] args) {
        
        String[] testPatterns = {
            "[A-Za-z]+",  // Valid
            "[0-9",       // Invalid
            "\\d{3}-\\d{2}", // Valid
            "(?invalid)"   // Invalid
        };
        
        for (String pattern : testPatterns) {
            ValidationResult result = validateRegex(pattern);
            System.out.println("Pattern: " + pattern);
            System.out.println("Valid: " + result.isValid());
            
            if (!result.isValid()) {
                System.out.println("Error: " + result.getError());
                System.out.println("Position: " + result.getErrorPosition());
            }
            System.out.println();
        }
    }
    
    public static ValidationResult validateRegex(String pattern) {
        try {
            Pattern.compile(pattern);
            return new ValidationResult(true, null, -1);
        } catch (PatternSyntaxException e) {
            return new ValidationResult(false, e.getDescription(), e.getIndex());
        }
    }
    
    static class ValidationResult {
        private final boolean valid;
        private final String error;
        private final int errorPosition;
        
        public ValidationResult(boolean valid, String error, int errorPosition) {
            this.valid = valid;
            this.error = error;
            this.errorPosition = errorPosition;
        }
        
        public boolean isValid() { return valid; }
        public String getError() { return error; }
        public int getErrorPosition() { return errorPosition; }
    }
}

This example shows a practical approach to regex validation. The validateRegex method attempts to compile the pattern. If successful, it returns a positive result. If a PatternSyntaxException occurs, it captures the error details.

The ValidationResult class encapsulates the validation outcome. This approach is useful in user-facing applications where you need to provide feedback about invalid patterns. The error details help users correct their regex syntax.

PatternSyntaxException in Real-World Scenarios

This example demonstrates handling PatternSyntaxException in a configuration scenario. We'll load regex patterns from a properties file and handle syntax errors gracefully. This mimics real-world applications where patterns may come from external sources.

ConfigRegexLoader.java
package com.zetcode;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.Properties;
import java.util.regex.Pattern;
import java.util.regex.PatternSyntaxException;

public class ConfigRegexLoader {

    public static void main(String[] args) {
        
        try {
            Properties props = new Properties();
            props.load(new FileInputStream("regex_config.properties"));
            
            String emailPattern = props.getProperty("email.regex");
            String phonePattern = props.getProperty("phone.regex");
            
            try {
                Pattern emailRegex = Pattern.compile(emailPattern);
                System.out.println("Email pattern compiled successfully");
            } catch (PatternSyntaxException e) {
                System.out.println("Invalid email pattern: " + e.getDescription());
            }
            
            try {
                Pattern phoneRegex = Pattern.compile(phonePattern);
                System.out.println("Phone pattern compiled successfully");
            } catch (PatternSyntaxException e) {
                System.out.println("Invalid phone pattern: " + e.getDescription());
            }
            
        } catch (IOException e) {
            System.out.println("Error loading configuration: " + e.getMessage());
        }
    }
}

This code loads regex patterns from a properties file. Each pattern is validated separately, with detailed error reporting for invalid patterns. This approach ensures one bad pattern doesn't prevent others from being used.

In real applications, you might log these errors or notify administrators. The key is providing enough detail to fix the configuration. The PatternSyntaxException gives all needed information to diagnose the problem.

Custom Error Messages for PatternSyntaxException

This example shows how to create user-friendly error messages based on PatternSyntaxException details. We'll parse the exception to generate more accessible explanations. This is helpful when presenting errors to non-technical users.

UserFriendlyErrors.java
package com.zetcode;

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

public class UserFriendlyErrors {

    public static void main(String[] args) {
        
        String[] testPatterns = {
            "[a-z", 
            "a{5,2}", 
            "(?invalid)", 
            "\\"
        };
        
        for (String pattern : testPatterns) {
            try {
                Pattern.compile(pattern);
            } catch (PatternSyntaxException e) {
                System.out.println("Pattern: " + pattern);
                System.out.println("User-friendly error:");
                System.out.println(getUserFriendlyError(e) + "\n");
            }
        }
    }
    
    public static String getUserFriendlyError(PatternSyntaxException e) {
        String description = e.getDescription().toLowerCase();
        int index = e.getIndex();
        String pattern = e.getPattern();
        
        if (description.contains("unclosed character class")) {
            return "Missing closing ']' for character class at position " + index;
        } else if (description.contains("illegal repetition")) {
            return "Invalid number range at position " + index + 
                   " (first number must be less than second)";
        } else if (description.contains("unknown look-behind")) {
            return "Invalid look-behind syntax at position " + index;
        } else if (description.contains("unterminated escape sequence")) {
            return "Incomplete escape sequence at position " + index;
        } else {
            return "Invalid regular expression syntax at position " + index;
        }
    }
}

This example transforms technical error messages into user-friendly explanations. The getUserFriendlyError method analyzes the exception and returns a simplified message. Each error type gets a custom explanation.

The method checks the exception's description to determine the error type. It then constructs a message that's easier for non-technical users to understand. The error position is still included for reference.

PatternSyntaxException with Flags

This example demonstrates how pattern flags can affect syntax validation. Some invalid patterns without flags become valid with certain flags. We'll show cases where flags change the syntax requirements.

FlagSyntaxEffects.java
package com.zetcode;

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

public class FlagSyntaxEffects {

    public static void main(String[] args) {
        
        // This pattern is invalid without COMMENTS flag
        String patternWithComments = "(?x) # This is a comment\n\\d+";
        
        try {
            // Try without COMMENTS flag (should fail)
            Pattern.compile(patternWithComments);
        } catch (PatternSyntaxException e) {
            System.out.println("Without COMMENTS flag:");
            System.out.println(e.getDescription() + "\n");
        }
        
        try {
            // Try with COMMENTS flag (should succeed)
            Pattern.compile(patternWithComments, Pattern.COMMENTS);
            System.out.println("With COMMENTS flag: Pattern compiled successfully");
        } catch (PatternSyntaxException e) {
            System.out.println("Unexpected error with COMMENTS flag:");
            System.out.println(e.getDescription());
        }
        
        // Another example with CASE_INSENSITIVE
        String badUnicode = "(?i)\\x{invalid}";
        
        try {
            Pattern.compile(badUnicode);
        } catch (PatternSyntaxException e) {
            System.out.println("\nUnicode error:");
            System.out.println(e.getDescription());
        }
    }
}

This example shows how pattern flags can affect syntax validation. The first pattern contains a comment, which is only valid with the COMMENTS flag. Without the flag, it triggers a PatternSyntaxException.

The second part demonstrates that flags don't make all patterns valid. The invalid Unicode escape sequence still fails even with CASE_INSENSITIVE flag. Understanding these interactions helps debug complex regex issues.

Source

Java PatternSyntaxException Documentation

In this article, we've covered the PatternSyntaxException in detail. We explored its methods, demonstrated common error scenarios, and showed practical handling techniques. Understanding this exception is crucial for robust regex processing.

Author

My name is Jan Bodnar, and I am a dedicated programmer with many years of experience in the field. I began writing programming articles in 2007 and have since authored over 1,400 articles and eight e-books. With more than eight years of teaching experience, I am committed to sharing my knowledge and helping others master programming concepts.

List all Java tutorials.