1

I would like to test if a string contains insert and name, with any interceding characters. And if it does, I would like to print the match.

For the below code, only the third Pattern matches, and the entire line is printed. How can I match only insert...name?

    String x = "aaa insert into name sdfdf";
    Matcher matcher = Pattern.compile("insert.*name").matcher(x);
    if (matcher.matches()) 
        System.out.print(matcher.group(0));  
    matcher = Pattern.compile(".*insert.*name").matcher(x);
    if (matcher.matches()) 
        System.out.print(matcher.group(0));  
    matcher = Pattern.compile(".*insert.*name.*").matcher(x);
    if (matcher.matches()) 
        System.out.print(matcher.group(0));  
ab11
  • 19,320
  • 39
  • 109
  • 199
  • Possible duplicate of [Check if string contains all strings from array](https://stackoverflow.com/questions/43409630/check-if-string-contains-all-strings-from-array) – ctwheels Jan 10 '18 at 20:10
  • Why not just use `insert.*name`? If that matches, it's in the string. – ctwheels Jan 10 '18 at 20:16

3 Answers3

1

try to use group like this .*(insert.*name).*

Matcher matcher = Pattern.compile(".*(insert.*name).*").matcher(x);
if (matcher.matches()) {
    System.out.print(matcher.group(1));
    //-----------------------------^
}

Or in your case you can just use :

x = x.replaceAll(".*(insert.*name).*", "$1");

Both of them print :

insert into name
YCF_L
  • 51,266
  • 13
  • 85
  • 129
  • 1
    If that's the case, why not just match `insert.*name`? – ctwheels Jan 10 '18 at 20:15
  • @ctwheels if you use `insert.*name` what is the expected result? – YCF_L Jan 10 '18 at 20:17
  • The expected result would be exactly that: `insert into name` – ctwheels Jan 10 '18 at 20:18
  • @YCF_L thanks, any suggestion how to make this work if `x` contains new line characters? `y = "\n aaa insert into name sdfdf \n";` – ab11 Jan 10 '18 at 20:18
  • @ab11 Use [`Pattern.DOTALL`](https://stackoverflow.com/questions/3651725/match-multiline-text-using-regular-expression) – ctwheels Jan 10 '18 at 20:19
  • @ctwheels i don't think this is correct, If i understand your suggest I can write this demo https://ideone.com/ysiUeS – YCF_L Jan 10 '18 at 20:20
  • @ab11 correct as @ctwheets mention you can use `Matcher matcher = Pattern.compile(".*(insert.*name).*", Pattern.DOTALL).matcher(x);` – YCF_L Jan 10 '18 at 20:22
  • @YCF_L It does work: https://ideone.com/5wanDH. Also see anubhava's answer for the same code. – ctwheels Jan 10 '18 at 20:22
  • aah you use `matcher.group(0)` yes you are correct ;) – YCF_L Jan 10 '18 at 20:23
  • @YCF_L you also need to use `.find()` instead of `.matches()` – ctwheels Jan 10 '18 at 20:23
  • 2
    @ctwheels already anubhava do all what you said in his answer ';(, but I still want to go with the second solution instead – YCF_L Jan 10 '18 at 20:24
  • @YCF_L @ctwheels, when I add `Pattern.DOTALL`, I get match if a `\n` occurs between `insert` and `name`, can I match this: `"\n aaa insert into name sdfdf \n";` but not `"\n aaa insert into \n name sdfdf \n";`? – ab11 Jan 10 '18 at 20:29
  • 1
    @ab11 you can enable/disable flags within the pattern itself: `insert(?s).*(?-s)name` or just use `[\s\S]` instead of `.` – ctwheels Jan 10 '18 at 20:30
1

You just need to use find() instead of matches() in your code:

String x = "aaa insert into name sdfdf";
Matcher matcher = Pattern.compile("insert.*?name").matcher(x);
if (matcher.find()) 
    System.out.print(matcher.group(0));

matches() expects you to match entire input string whereas find() lets you match your regex anywhere in the input.

Also suggest you to use .*? instead of .*, in case your input may contain multiple instances of index ... name pairs.

This code sample will output:

insert into name
anubhava
  • 713,503
  • 59
  • 514
  • 593
0

Just use multiple positive lookaheads:

(?=.*insert)(?=.*name).+

See a demo on regex101.com.

Jan
  • 40,932
  • 8
  • 45
  • 77