1

I need to write a regex expression for validating if a sql query in the form of a string begins with a SELECT and ends with a LIMIT followed by a number. Of course, this needs to be case insensitive and should be able to ignore preceding and trailing whitespaces.

Valid String:
1. select * from table where col='anything' limit 10
2. SELECT * from table where col='anything' LIMIT 10

Invalid String:
1. select * from table where col='anything'
2. SELECT * from table where col='anything'

I have tried the following, but it is not matching for any case and printing false for all four cases:

public class Main {

    private static final String  regex   = "^SELECT(?:[^;']|(?:'[^']+'))+ LIMIT + \\d+;\\s*$";
    private static final Pattern pattern = Pattern.compile(regex, Pattern.MULTILINE | Pattern.CASE_INSENSITIVE);

    private static boolean matchesPattern(String query) {
        return pattern.matcher(query).matches();
    }

    public static void main(String[] args) {

        String[] queries = {
                "select * from table where col='anything'",             // should print false, as no limit condition
                "select * from table where col='anything' limit 10",    // should print true
                "SELECT * from table where col='anything'",             // should print false, as no limit condition
                "SELECT * from table where col='anything' LIMIT 10"     // should print true
        };

        for (String query: queries){
            System.out.println(matchesPattern(query));
        }
    }
}
2
  • 1
    I'm not really a pro in regex, but I think you should remove the + before and after LIMIT. they mean 'one or more times'. Commented Jul 21, 2017 at 9:35
  • 1
    Can't ' be escaped in the '...' string? BTW, you just need to make ; optional and remove the space before \\d+ : ^SELECT(?:[^;']|(?:'[^']+'))+ LIMIT +\d+;?\s*$. Commented Jul 21, 2017 at 9:35

2 Answers 2

2

Your regex isn't right.
For your problem something like that is suitable:

"^(SELECT|select).*(LIMIT|limit) (\\d+);$"

Keep in mind that in your test you dont have a ; at the end of your queries, so they will never return true.

Sign up to request clarification or add additional context in comments.

Comments

1

Note that a fix for the current pattern is to remove a space before \\d+ and make the ; optional by adding a ? quantifier after it. Use

String regex = "^SELECT(?:[^;']|(?:'[^']+'))+ LIMIT +\\d+;?\\s*$";

See a regex demo.

In the LIMIT + \\d+ part matches 2 or more spaces after LIMIT and the regex will fail to match anything if there is just 1 space.

None of the correct samples ends with ; thus either remove it or make optional.

Note that '...' may contain escape single quotes, you will need to adjust the pattern. If they are escaped with a single quote use '[^']*(?:''[^']*)*' instead of '[^']+' in your pattern.

1 Comment

Added the pattern to the answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.