9

I need to change a piece of code which includes this:

string.indexOf("bc")

How can this be changed by a solution that skips the occurrence of "bc" if it is preceded by the letter "a".

I don't want to find these:

abc

but only:

xbc

where x can be anything but a (even empty).

I think I could just put in a condition that checks if the index i-1 == a, and if true call the indexOf method again. But I don't think that would result in very beautiful code.

How would a solution that uses regular expressions look like?

Edit: Just a hint after seeing some responses. It would be nice to get not only the regular expression, but also the required API calls to find the index.

4 Answers 4

19

As requested a more complete solution:

    /** @return index of pattern in s or -1, if not found */
public static int indexOf(Pattern pattern, String s) {
    Matcher matcher = pattern.matcher(s);
    return matcher.find() ? matcher.start() : -1;
}

call:

int index = indexOf(Pattern.compile("(?<!a)bc"), "abc xbc");
Sign up to request clarification or add additional context in comments.

2 Comments

Well, my Edit was more a response to the answers that only contained a single regular expression. But thanks anyway, this looks nice.
if you wanted to do indexing on top of it you could do: public static int indexOf(String regex, String s, int index) { Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(s); return matcher.find(index) ? matcher.start() : -1; } ... int index = indexOf("(?<!a)bc", "abc xbc", 2);
5

You could use a regex with a negative lookbehind:

(?<!a)bc

Unfortunately to reproduce .indexOf with Regex in Java is still a mess:

Pattern pattern = Pattern.compile("(?!a)bc");
Matcher matcher = pattern.matcher("abc xbc");
if (matcher.find()) {
    return matcher.start();
}

4 Comments

Negative lookbehind seems to hit the nail pretty much. Too bad there isnt a .indexof(Regex) in the API.
@HansWiener sorry it should be matcher.find() (see? It's a mess :) ).
Ah its just a typo, which version should I accept now? Thers also a typo in the regex expression (missing <)
Honestly what is the point of finding a match to a reg exp if then there is no way to retrieve the starting or ending index of the pattern found in the String? This is why I refuse to use Pattern and Matcher classes. It's too cryptic and way more frustrating and time-wasting than helpful. You gotta scrub through the String char by char. You complete your objective much faster with much less frustration I promise
2

To add to Arne's answer - if you wanted to also add indexing:

public static int indexOf(String regex, String s, int index)
{
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(s);
    return matcher.find(index) ? matcher.start() : -1;
}

call:

int index = indexOf("(?<!a)bc", "abc xbc", 2);

Comments

1

Use regex to find the String that matches your criteria, and then find the index of that String.

int index = -1;
Pattern p = Pattern.compile("[^Aa]?bc");
Matcher m = p.matcher(string);
if (m.find()) {
    index = m.start();
}

Something like this. Where 'string' is the text you're searching and 'index' holds the location of the string that is found. (index will be -1 if not found.) Also note that the pattern is case sensitive unless you set a flag.

Comments

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.