Take the 2-minute tour ×

How do I change my pattern to look further back in the string?

When the word "paragraph" is behind the pattern (alpha) then the match is false, otherwise it's true.

So for example this would have 5 matches:

acts on behalf of any person referred to in act (a), (b), (c), (d) or (e) paragraph (f);

They would be: (a) (b) (c) (d) (e)

And this would have 0 matches:


share|improve this question
I didn't understand the 2nd paragraph of your question. :) –  Kent Jan 31 '13 at 12:57
@Kent How about now? –  ThreaT Jan 31 '13 at 12:59
@ThreaT yep, better, you could think your problem in an opposite way. try to match those "false" case. it could make it a lot easier. check my answer for detail. –  Kent Jan 31 '13 at 13:18
add comment

3 Answers

up vote 2 down vote accepted

That's not possible for any length with a simple lookbehind. Java regex flavor only allow finite-length lookbehind (i.e. you can do (?<=x{2,10}) but not (?<=x*)).

If you can reduce the problem to “the word paragraph should not appear in the 100 letters preceding (a)”, that works:


If you really want unbounded distance and if your regex is flexible and can start at the beginning of the input and match only one (ref), you can approximate the wanted behavior with negative look-ahead (which needs not be finite):


Will match test test (a) but not paragraph test (a).

That is a trick though that can become quite complex to maintain, has downsides (like matching only once) and ultimately there are probably better ways to solve your problem. For instance, you could match all those ([a-z]) then check whether the string contains paragraph, eliminating all matches that come after its position.

PS: instead of Pattern.compile("[aA][bB][cC]"), consider using Pattern.compile("abc", Pattern.CASE_INSENSISIVE) or Pattern.compile("(?i)abc") (if the whole regex is case-insensitive) or Pattern.compile("(?i:abc)dEf") (if only abc is case-insensitive).

share|improve this answer
Can you try that in www.gskinner.com/RegExr? For some reason test test (a) and paragraph test (a) don't work for me –  ThreaT Jan 31 '13 at 13:13
RegExr uses ActionScript 3's regex flavor: gskinner.com/blog/archives/2008/03/regexr_free_onl.html –  instanceof me Jan 31 '13 at 13:17
Yes. Can you please post a link to it demonstrating your pattern. –  ThreaT Jan 31 '13 at 13:18
Try it here in Java: fiddle.re/xd8b –  instanceof me Jan 31 '13 at 13:18
@streetpc (a) paragraph should match too right? –  Kent Jan 31 '13 at 13:21
show 1 more comment

you could do in this way:

(I ignored the case intensive part, you could add by yourself)


This is checking if there is match for your FALSE case. which is, a (a) with paragraph ahead.

then you check if the line match the regex above, if true, then you skip, if false, then you take it.

test with grep: (-v is for displaying not-matched lines)

kent$  cat test.txt
Paragraph (a)
(b) (c)
foo bar Paragraph (a) (b)
foo bar Paragraph (some) (a) (b)
foo bar (a) (b) Paragraph (c)

kent$  grep -v '.*Paragraph.*\(a\)' test.txt
(b) (c)
foo bar (a) (b) Paragraph (c)

there is a little problem is, if the line has no Paragraph and no (a), would be matched as well. I think this is also easy to be fixed in your java program by something like:

if (!m.find() && line.indexOf("(a)")>0) ...your match   
share|improve this answer
Kent can you try and run this pattern on www.gskinner.com/RegExr and share a link to it –  ThreaT Jan 31 '13 at 13:20
@ThreaT I was avoiding to do that. :) –  Kent Jan 31 '13 at 13:21
add comment

You can do it like this:

// If "paragraph" (case insensitive) does not appear before any (<alpha>)
// It means that "paragraph" (case insensitive) will appear after one (<alpha>)
// OR it does not appear at all in the string.
if (!str.matches("(?s)(?:(?!\\([a-z]+\\)).)*(?i:paragraph).*")) {
    // Use the Matcher loop to extract the text that matches pattern "\\([a-z]+\\)"
    Pattern p = Pattern.compile("\\([a-z]+\\)");
    Matcher m = p.matcher(str);

    while (m.find()) {

Just check that paragraph doesn't appear before all the (<alpha>) before extracting all the (<alpha>). This will work for any length of the string.

share|improve this answer
add comment

Your Answer


