2

I have a question about Java regular expression. How to find a regular expression pattern without include it in the result?

For example if the string is "1ab 2cd 3se 4ab" and I want to get the number that is followed by ab without including ab in the result. The final result is "1 4"

Mark Rotteveel
  • 100,966
  • 191
  • 140
  • 197
N.IT
  • 177
  • 1
  • 11

3 Answers3

2

You are looking for look-around mechanisms, in particular positive look-ahead which is zero-width (it doesn't consume matched part, nor includes it in result).

In your case regex can look like \\d(?=ab) which means:

  • \\d find single digit
  • (?=ab) which is followed by ab

If your input can contain 1abc which you don't want to accept you can add word boundary \b after ab like \\d(?=ab\\b).

Pshemo
  • 122,468
  • 25
  • 185
  • 269
  • sir, thanks for your feedback. up-votes. if the problem is more complex your way is more effectively. I'd like to use a `Matcher` too. – holi-java Jun 03 '17 at 14:53
0

Do you mean something like groups for example (\\d+)ab

String str = "1ab 2cd 3se 4ab";
Pattern pat = Pattern.compile("(\\d+)" + "ab");
Matcher mat = pat.matcher(str);
while (mat.find()) {
    System.out.println(mat.group(1));
    //----------------------^^------get the group(1) which mean get just the digit part
}

Output

1
4

  1. (\\d+) group of one or more digit
  2. ab followed by ab

Here is regex demo

Youcef LAIDANI
  • 55,661
  • 15
  • 90
  • 140
0

How about this?

                     // v--- replace "ab" with ""
String it=s.replaceAll("ab|\\s*\\dab\\w+|\\s*\\d(?:[^a]|\\w[^b])\\w*", "").trim(); 
//                                 |                |       |
//              replace "{digit}ab*" with ""        |       |
//                                                  |       |
//                                                  |       |
//                       replace " {digit}[not a]*" with "" |
//                                                          |                  
//                                                          |
//                                          replace " {digit}?[not b]*" with ""

Output

"1ab 2cd 3se 4ab" -> "1 4"
"1ab 2cd 3se 5ac 4ab" -> "1 4"
"1ab 2cd 3se 4ab 6se" -> "1 4"
"1ab 2cd 3se 4ab 1qwer" -> "1 4"
"1qwer 2cd 3se 4ab 6se" -> "4"
"2cd 3se 4ab 6se 1qwer" -> "4"
"1abcd 2cd 3se 4ab" -> "4"
holi-java
  • 29,655
  • 7
  • 72
  • 83
  • 2
    Will fail for `5ac`. – Pshemo Jun 03 '17 at 13:28
  • @Pshemo thanks for your feedback. but I think I solved the OP's problem. – holi-java Jun 03 '17 at 13:30
  • Will also fail for any non `ab` at the end the string i.e `6se` etc since they aren't followed by space – degant Jun 03 '17 at 13:32
  • @degant yeah, but OP did not say it more. I'll fix my answer meet your needs. – holi-java Jun 03 '17 at 13:34
  • @degant thanks for your feedback. how about it now? – holi-java Jun 03 '17 at 13:49
  • @Pshemo thanks for your feedback. how about it now? – holi-java Jun 03 '17 at 13:49
  • Better, but this still assumes that OP actually have input in form: one digit, to letters. Lets just hope that example is very precise and something like `1qwer` will never appear. – Pshemo Jun 03 '17 at 13:52
  • @Pshemo yes, sir. but his problem is so simpler, according to [KISS](https://en.wikipedia.org/wiki/KISS_principle) principle so I uses `replaceAll` rather than a `Matcher` . – holi-java Jun 03 '17 at 13:58
  • @Pshemo sir, for `1qwer` you can add `\\w*` at the end of the regex to fix bug as further. – holi-java Jun 03 '17 at 14:01
  • @Pshemo sir, How about it now? – holi-java Jun 03 '17 at 14:23
  • It is working so I removed my down-vote, but I am not so sure about KISS here. You are just moving not too big confusion from `while(matcher.find()){matcher.group()}` structure into regex, which is IMO more complex now and will be harder to maintain (lets say that OP now wants to search for `[digit]abcdefg` - you are going to create spaghetti here). But let OP decide if this is what (s)he wants. – Pshemo Jun 03 '17 at 14:50
  • @Pshemo yes, sir. if the complex grows further I prefer to use a `Matcher` too. – holi-java Jun 03 '17 at 14:51