title: Strangeness with negative lookahead assertion in Java regular expression
body: <p>I'm struggling to understand the behaviour of regular expressions in Java and have encountered something that seems very strange. In the code below, the test fails all of a sudden for reasons I don't understand at the test with the message label "6 letters matched, negative" (the subsequent two tests fail as well). Have I been staring at this for too long or is there indeed something strange happening? I don't this has to do with the variable-length negative lookahead assertion (?!X), but I'd be happy to hear any theories, or even a confirmation that others are experiencing the same issue and that it's not specific to my JVM. Sorry that the regular expression is so contrived, but you don't want to see the real thing :)</p>
  
  <pre><code>// $ java -version
  // java version "1.7.0_10"
  // Java(TM) SE Runtime Environment (build 1.7.0_10-b18)
  // Java HotSpot(TM) 64-Bit Server VM (build 23.6-b04, mixed mode)
  
  // test of word without agreement
  String test = "plusieurs personne sont";
  
  // match the pattern with curly braces
  assertTrue("no letters matched", Pattern.compile("plusieurs personne\\b").matcher(test).find());
  assertTrue("1 letters matched", Pattern.compile("plusieurs personn\\p{Alpha}{1,100}\\b").matcher(test).find());
  assertTrue("2 letters matched", Pattern.compile("plusieurs person\\p{Alpha}{1,100}\\b").matcher(test).find());
  assertTrue("3 letters matched", Pattern.compile("plusieurs perso\\p{Alpha}{1,100}\\b").matcher(test).find());
  assertTrue("4 letters matched", Pattern.compile("plusieurs pers\\p{Alpha}{1,100}\\b").matcher(test).find());
  assertTrue("5 letters matched", Pattern.compile("plusieurs per\\p{Alpha}{1,100}\\b").matcher(test).find());
  assertTrue("6 letters matched", Pattern.compile("plusieurs pe\\p{Alpha}{1,100}\\b").matcher(test).find());
  assertTrue("7 letters matched", Pattern.compile("plusieurs p\\p{Alpha}{1,100}\\b").matcher(test).find());
  assertTrue("8 letters matched", Pattern.compile("plusieurs \\p{Alpha}{1,100}\\b").matcher(test).find());
  
  // match the negative pattern (without s or x) with curly braces
  assertTrue("no letters matched, negative", Pattern.compile("plusieurs (?!personne[sx])\\w+").matcher(test).find());
  assertTrue("1 letters matched, negative", Pattern.compile("plusieurs (?!personn\\p{Alpha}{1,100}[sx])\\w+").matcher(test).find());
  assertTrue("2 letters matched, negative", Pattern.compile("plusieurs (?!person\\p{Alpha}{1,100}[sx])\\w+").matcher(test).find());
  assertTrue("3 letters matched, negative", Pattern.compile("plusieurs (?!perso\\p{Alpha}{1,100}[sx])\\w+").matcher(test).find());
  assertTrue("4 letters matched, negative", Pattern.compile("plusieurs (?!pers\\p{Alpha}{1,100}[sx])\\w+").matcher(test).find());
  assertTrue("5 letters matched, negative", Pattern.compile("plusieurs (?!per\\p{Alpha}{1,100}[sx])\\w+").matcher(test).find());
  // the assertion below fails (is false) for reasons unknown
  assertTrue("6 letters matched, negative", Pattern.compile("plusieurs (?!pe\\p{Alpha}{1,100}[sx])\\w+").matcher(test).find());
  assertTrue("7 letters matched, negative", Pattern.compile("plusieurs (?!p\\p{Alpha}{1,100}[sx])\\w+").matcher(test).find());
  assertTrue("8 letters matched, negative", Pattern.compile("plusieurs (?!\\p{Alpha}{1,100}[sx])\\w+").matcher(test).find());
  </code></pre>