0

I have a one liner string that looks like this:

My db objects are db.main_flow_tbl, 'main_flow_audit_tbl', main_request_seq and MAIN_SUBFLOW_TBL.

I want to use regular expressions to return database tables that start with main but do not contain words audit or seq, and irrespective of the case. So in the above example strings main_flow_tbl and MAIN_SUBFLOW_TBL shall return. Can someone help me with this please?

2

3 Answers 3

2

Here is a fully regex based solution:

public static void main(String[] args) throws Exception {
    final String in = "My db objects are db.main_flow_tbl, 'main_flow_audit_tbl', main_request_seq and MAIN_SUBFLOW_TBL.";
    final Pattern pat = Pattern.compile("main_(?!\\w*?(?:audit|seq))\\w++", Pattern.CASE_INSENSITIVE);
    final Matcher m = pat.matcher(in);
    while(m.find()) {
        System.out.println(m.group());
    }
}

Output:

main_flow_tbl
MAIN_SUBFLOW_TBL

This assumes that table names can only contain A-Za-Z_ which \w is the shorthand for.

Pattern breakdown:

  • main_ is the liternal "main" that you want tables to start with
  • (?!\\w*?(?:audit|seq)) is a negative lookahead (not followed by) which takes any number of \w characters (lazily) followed by either "audit" or "seq". This excludes tables names that contain those sequences.
  • \\w++ consume any table characters possesively.

EDIT

OP's comment they may contain numbers as well

In this case use this pattern:

main_(?![\\d\\w]*?(?:audit|seq))[\\d\\w]++

i.e. use [\\d\\w] rather than \\w

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

7 Comments

they may contain numbers as well
Nice solution! I was still tossing around on the negative lookahead
Can you please explain it to me to get the maximum benefit?
@YasserAlMasri There is a breakdown of the pattern, what parts do you need me to expand?
my particular question is that I tried this: (?i)main_(?!.*audit|seq)[a-zA-Z0-9_]* but it kept eliminating all the line once audit or seq is found. What's the difference that made yours do the trick?
|
0
String str
while ((str.startsWith("main"))&&!str.contains("audit")||!str.contains("seq")){
   //your code here
}

3 Comments

I asked for regular expressions
@YasserAlMasri: Is this homework? Why does it have to be a regular expression if there is a working alternative?
because it will be very tedious otherwise. What is str in your case? I don't have anything to capture an array of strings that really contain the tables. It just can be anything with in the string
0

If the string matches

    ^main_(\w_)*(?!(?:audit|seq))

it should be what you want...

1 Comment

Almost. You don't have the case insensitive flag. You have a start anchor so it won't find patterns in Strings; which is what the OP wants. And your match group would capture up to the sequences the OP doesn't want. So rather than excluding names containing seq like table_seq this would capture table_. In short test your code before posting.

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.