[Pcre-svn] [637] code/trunk: Permit quantifiers on parenthes…

トップ ページ
このメッセージを削除
著者: Subversion repository
日付:  
To: pcre-svn
題目: [Pcre-svn] [637] code/trunk: Permit quantifiers on parenthesized assertions.
Revision: 637
          http://vcs.pcre.org/viewvc?view=rev&revision=637
Author:   ph10
Date:     2011-07-24 18:44:12 +0100 (Sun, 24 Jul 2011)


Log Message:
-----------
Permit quantifiers on parenthesized assertions.

Modified Paths:
--------------
    code/trunk/ChangeLog
    code/trunk/doc/pcrecompat.3
    code/trunk/doc/pcrepattern.3
    code/trunk/pcre_compile.c
    code/trunk/pcre_dfa_exec.c
    code/trunk/pcre_internal.h
    code/trunk/testdata/testinput1
    code/trunk/testdata/testinput11
    code/trunk/testdata/testinput2
    code/trunk/testdata/testinput7
    code/trunk/testdata/testoutput1
    code/trunk/testdata/testoutput11
    code/trunk/testdata/testoutput2
    code/trunk/testdata/testoutput7


Modified: code/trunk/ChangeLog
===================================================================
--- code/trunk/ChangeLog    2011-07-24 17:43:51 UTC (rev 636)
+++ code/trunk/ChangeLog    2011-07-24 17:44:12 UTC (rev 637)
@@ -172,6 +172,11 @@
     matched the line "0102" twice. The same bug affected patterns that started
     with a backwards assertion. For example /\b01|\b02/ also matched "0102"
     twice. 
+    
+33. Previously, PCRE did not allow quantification of assertions. However, Perl 
+    does, and because of capturing effects, quantifying parenthesized 
+    assertions may at times be useful. Quantifiers are now allowed for 
+    parenthesized assertions.



Version 8.12 15-Jan-2011

Modified: code/trunk/doc/pcrecompat.3
===================================================================
--- code/trunk/doc/pcrecompat.3    2011-07-24 17:43:51 UTC (rev 636)
+++ code/trunk/doc/pcrecompat.3    2011-07-24 17:44:12 UTC (rev 637)
@@ -20,10 +20,12 @@
 .\"
 page.
 .P
-2. PCRE does not allow repeat quantifiers on assertions. Perl permits them, but
-they do not mean what you might think. For example, (?!a){3} does not assert
-that the next three characters are not "a". It just asserts that the next
-character is not "a" three times.
+2. PCRE allows repeat quantifiers only on parenthesized assertions, but they do
+not mean what you might think. For example, (?!a){3} does not assert that the
+next three characters are not "a". It just asserts that the next character is
+not "a" three times (in principle: PCRE optimizes this to run the assertion 
+just once). Perl allows repeat quantifiers on other assertions such as \b, but 
+these do not seem to have any use.
 .P
 3. Capturing subpatterns that occur inside negative lookahead assertions are
 counted, but their entries in the offsets vector are never set. Perl sets its
@@ -171,6 +173,6 @@
 .rs
 .sp
 .nf
-Last updated: 23 July 2011
+Last updated: 24 July 2011
 Copyright (c) 1997-2011 University of Cambridge.
 .fi


Modified: code/trunk/doc/pcrepattern.3
===================================================================
--- code/trunk/doc/pcrepattern.3    2011-07-24 17:43:51 UTC (rev 636)
+++ code/trunk/doc/pcrepattern.3    2011-07-24 17:44:12 UTC (rev 637)
@@ -1438,7 +1438,7 @@
   an escape such as \ed or \epL that matches a single character
   a character class
   a back reference (see next section)
-  a parenthesized subpattern (unless it is an assertion)
+  a parenthesized subpattern (including assertions)
   a recursive or "subroutine" call to a subpattern
 .sp
 The general repetition quantifier specifies a minimum and maximum number of
@@ -1829,12 +1829,30 @@
 that look behind it. An assertion subpattern is matched in the normal way,
 except that it does not cause the current matching position to be changed.
 .P
-Assertion subpatterns are not capturing subpatterns, and may not be repeated,
-because it makes no sense to assert the same thing several times. If any kind
-of assertion contains capturing subpatterns within it, these are counted for
-the purposes of numbering the capturing subpatterns in the whole pattern.
-However, substring capturing is carried out only for positive assertions,
-because it does not make sense for negative assertions.
+Assertion subpatterns are not capturing subpatterns. If such an assertion
+contains capturing subpatterns within it, these are counted for the purposes of
+numbering the capturing subpatterns in the whole pattern. However, substring
+capturing is carried out only for positive assertions, because it does not make
+sense for negative assertions.
+.P
+For compatibility with Perl, assertion subpatterns may be repeated, even though
+it makes no sense to assert the same thing several times. In practice, there 
+only three cases:
+.sp
+(1) If the quantifier is {0}, the assertion is never obeyed during matching. 
+However, it may contain internal capturing parenthesized groups that are called 
+from elsewhere via the
+.\" HTML <a href="#subpatternsassubroutines">
+.\" </a>
+subroutine mechanism.
+.\"
+.sp
+(2) If quantifier is {0,n} where n is greater than zero, it is treated as if it 
+were {0,1}. At run time, the rest of the pattern match is tried with and 
+without the assertion, the order depending on the greediness of the quantifier.
+.sp
+(3) If the minimum repetition is greater than zero, the quantifier is ignored. 
+The assertion is obeyed just once when encountered during matching.
 .
 .
 .SS "Lookahead assertions"
@@ -2761,6 +2779,6 @@
 .rs
 .sp
 .nf
-Last updated: 22 July 2011
+Last updated: 24 July 2011
 Copyright (c) 1997-2011 University of Cambridge.
 .fi


Modified: code/trunk/pcre_compile.c
===================================================================
--- code/trunk/pcre_compile.c    2011-07-24 17:43:51 UTC (rev 636)
+++ code/trunk/pcre_compile.c    2011-07-24 17:44:12 UTC (rev 637)
@@ -393,7 +393,7 @@
   "internal error: previously-checked referenced subpattern not found\0"
   "DEFINE group contains more than one branch\0"
   /* 55 */
-  "repeating a DEFINE group is not allowed\0"
+  "repeating a DEFINE group is not allowed\0"  /** DEAD **/
   "inconsistent NEWLINE options\0"
   "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0"
   "a numbered reference must not be zero\0"
@@ -4210,8 +4210,8 @@
     op_type = 0;                    /* Default single-char op codes */
     possessive_quantifier = FALSE;  /* Default not possessive quantifier */


-    /* Save start of previous item, in case we have to move it up to make space
-    for an inserted OP_ONCE for the additional '+' extension. */
+    /* Save start of previous item, in case we have to move it up in order to
+    insert something before it. */


     tempcode = previous;


@@ -4554,25 +4554,36 @@
       }


     /* If previous was a bracket group, we may have to replicate it in certain
-    cases. Note that at this point we can encounter only the "basic" BRA and
-    KET opcodes, as this is the place where they get converted into the more
-    special varieties. */
+    cases. Note that at this point we can encounter only the "basic" bracket
+    opcodes such as BRA and CBRA, as this is the place where they get converted
+    into the more special varieties such as BRAPOS and SBRA. A test for >=
+    OP_ASSERT and <= OP_COND includes ASSERT, ASSERT_NOT, ASSERTBACK,
+    ASSERTBACK_NOT, ONCE, BRA, CBRA, and COND. Originally, PCRE did not allow 
+    repetition of assertions, but now it does, for Perl compatibility. */


-    else if (*previous == OP_BRA  || *previous == OP_CBRA ||
-             *previous == OP_ONCE || *previous == OP_COND)
+    else if (*previous >= OP_ASSERT && *previous <= OP_COND)             
       {
       register int i;
       int len = (int)(code - previous);
       uschar *bralink = NULL;
       uschar *brazeroptr = NULL;


-      /* Repeating a DEFINE group is pointless */
+      /* Repeating a DEFINE group is pointless, but Perl allows the syntax, so 
+      we just ignore the repeat. */


       if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_DEF)
+        goto END_REPEAT;        
+
+      /* There is no sense in actually repeating assertions. The only potential 
+      use of repetition is in cases when the assertion is optional. Therefore, 
+      if the minimum is greater than zero, just ignore the repeat. If the 
+      maximum is not not zero or one, set it to 1. */   
+
+      if (*previous < OP_ONCE)    /* Assertion */
         {
-        *errorcodeptr = ERR55;
-        goto FAILED;
-        }
+        if (repeat_min > 0) goto END_REPEAT;
+        if (repeat_max < 0 || repeat_max > 1) repeat_max = 1;
+        } 


       /* The case of a zero minimum is special because of the need to stick
       OP_BRAZERO in front of it, and because the group appears once in the
@@ -4592,10 +4603,11 @@
         **   goto END_REPEAT;
         **   }


-        However, that fails when a group is referenced as a subroutine from
-        elsewhere in the pattern, so now we stick in OP_SKIPZERO in front of it
-        so that it is skipped on execution. As we don't have a list of which
-        groups are referenced, we cannot do this selectively.
+        However, that fails when a group or a subgroup within it is referenced
+        as a subroutine from elsewhere in the pattern, so now we stick in
+        OP_SKIPZERO in front of it so that it is skipped on execution. As we
+        don't have a list of which groups are referenced, we cannot do this
+        selectively.


         If the maximum is 1 or unlimited, we just have to stick in the BRAZERO
         and do no more at this point. However, we do need to adjust any
@@ -5860,12 +5872,12 @@
       skipbytes = 2;
       }


-    /* Process nested bracketed regex. Assertions may not be repeated, but
-    other kinds can be. All their opcodes are >= OP_ONCE. We copy code into a
-    non-register variable (tempcode) in order to be able to pass its address
-    because some compilers complain otherwise. */
+    /* Process nested bracketed regex. Assertions used not to be repeatable,
+    but this was changed for Perl compatibility, so all kinds can now be
+    repeated. We copy code into a non-register variable (tempcode) in order to
+    be able to pass its address because some compilers complain otherwise. */


-    previous = (bravalue >= OP_ONCE)? code : NULL;
+    previous = code;                   /* For handling repetition */
     *code = bravalue;
     tempcode = code;
     tempreqvary = cd->req_varyopt;     /* Save value before bracket */


Modified: code/trunk/pcre_dfa_exec.c
===================================================================
--- code/trunk/pcre_dfa_exec.c    2011-07-24 17:43:51 UTC (rev 636)
+++ code/trunk/pcre_dfa_exec.c    2011-07-24 17:44:12 UTC (rev 637)
@@ -159,11 +159,11 @@
   0,                             /* KetRmax                                */
   0,                             /* KetRmin                                */
   0,                             /* KetRpos                                */
+  0,                             /* Reverse                                */
   0,                             /* Assert                                 */
   0,                             /* Assert not                             */
   0,                             /* Assert behind                          */
   0,                             /* Assert behind not                      */
-  0,                             /* Reverse                                */
   0, 0, 0, 0, 0, 0,              /* ONCE, BRA, BRAPOS, CBRA, CBRAPOS, COND */
   0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */
   0, 0,                          /* CREF, NCREF                            */
@@ -227,11 +227,11 @@
   0,                             /* KetRmax                                */
   0,                             /* KetRmin                                */
   0,                             /* KetRpos                                */
+  0,                             /* Reverse                                */
   0,                             /* Assert                                 */
   0,                             /* Assert not                             */
   0,                             /* Assert behind                          */
   0,                             /* Assert behind not                      */
-  0,                             /* Reverse                                */
   0, 0, 0, 0, 0, 0,              /* ONCE, BRA, BRAPOS, CBRA, CBRAPOS, COND */
   0, 0, 0, 0, 0,                 /* SBRA, SBRAPOS, SCBRA, SCBRAPOS, SCOND  */
   0, 0,                          /* CREF, NCREF                            */


Modified: code/trunk/pcre_internal.h
===================================================================
--- code/trunk/pcre_internal.h    2011-07-24 17:43:51 UTC (rev 636)
+++ code/trunk/pcre_internal.h    2011-07-24 17:44:12 UTC (rev 637)
@@ -1448,16 +1448,16 @@
   /* The assertions must come before BRA, CBRA, ONCE, and COND, and the four
   asserts must remain in order. */


-  OP_ASSERT,         /* 118 Positive lookahead */
-  OP_ASSERT_NOT,     /* 119 Negative lookahead */
-  OP_ASSERTBACK,     /* 120 Positive lookbehind */
-  OP_ASSERTBACK_NOT, /* 121 Negative lookbehind */
-  OP_REVERSE,        /* 122 Move pointer back - used in lookbehind assertions */
+  OP_REVERSE,        /* 118 Move pointer back - used in lookbehind assertions */
+  OP_ASSERT,         /* 119 Positive lookahead */
+  OP_ASSERT_NOT,     /* 120 Negative lookahead */
+  OP_ASSERTBACK,     /* 121 Positive lookbehind */
+  OP_ASSERTBACK_NOT, /* 122 Negative lookbehind */


- /* ONCE, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come after the assertions,
- with ONCE first, as there's a test for >= ONCE for a subpattern that isn't an
- assertion. The POS versions must immediately follow the non-POS versions in
- each case. */
+ /* ONCE, BRA, BRAPOS, CBRA, CBRAPOS, and COND must come immediately after the
+ assertions, with ONCE first, as there's a test for >= ONCE for a subpattern
+ that isn't an assertion. The POS versions must immediately follow the non-POS
+ versions in each case. */

   OP_ONCE,           /* 123 Atomic group */
   OP_BRA,            /* 124 Start of non-capturing bracket */
@@ -1550,7 +1550,7 @@
   "class", "nclass", "xclass", "Ref", "Refi",                     \
   "Recurse", "Callout",                                           \
   "Alt", "Ket", "KetRmax", "KetRmin", "KetRpos",                  \
-  "Assert", "Assert not", "AssertB", "AssertB not", "Reverse",    \
+  "Reverse", "Assert", "Assert not", "AssertB", "AssertB not",    \
   "Once",                                                         \
   "Bra", "BraPos", "CBra", "CBraPos",                             \
   "Cond",                                                         \
@@ -1619,11 +1619,11 @@
   1+LINK_SIZE,                   /* KetRmax                                */ \
   1+LINK_SIZE,                   /* KetRmin                                */ \
   1+LINK_SIZE,                   /* KetRpos                                */ \
+  1+LINK_SIZE,                   /* Reverse                                */ \
   1+LINK_SIZE,                   /* Assert                                 */ \
   1+LINK_SIZE,                   /* Assert not                             */ \
   1+LINK_SIZE,                   /* Assert behind                          */ \
   1+LINK_SIZE,                   /* Assert behind not                      */ \
-  1+LINK_SIZE,                   /* Reverse                                */ \
   1+LINK_SIZE,                   /* ONCE                                   */ \
   1+LINK_SIZE,                   /* BRA                                    */ \
   1+LINK_SIZE,                   /* BRAPOS                                 */ \


Modified: code/trunk/testdata/testinput1
===================================================================
--- code/trunk/testdata/testinput1    2011-07-24 17:43:51 UTC (rev 636)
+++ code/trunk/testdata/testinput1    2011-07-24 17:44:12 UTC (rev 637)
@@ -4190,4 +4190,48 @@
 /^(?:a|ab)+c/
     aaaabc


+/(?=abc){3}abc/+
+    abcabcabc
+    ** Failers
+    xyz  
+    
+/(?=abc)+abc/+
+    abcabcabc
+    ** Failers
+    xyz  
+    
+/(?=abc)++abc/+
+    abcabcabc
+    ** Failers
+    xyz  
+    
+/(?=abc){0}xyz/
+    xyz 
+
+/(?=abc){1}xyz/
+    ** Failers
+    xyz 
+    
+/(?=(a))?./
+    ab
+    bc
+      
+/(?=(a))??./
+    ab
+    bc
+
+/^(?=(a)){0}b(?1)/
+    backgammon
+
+/^(?=(?1))?[az]([abc])d/
+    abd 
+    zcdxx 
+
+/^(?!a){0}\w+/
+    aaaaa
+
+/(?<=(abc))?xyz/
+    abcxyz
+    pqrxyz 
+
 /-- End of testinput1 --/


Modified: code/trunk/testdata/testinput11
===================================================================
--- code/trunk/testdata/testinput11    2011-07-24 17:43:51 UTC (rev 636)
+++ code/trunk/testdata/testinput11    2011-07-24 17:44:12 UTC (rev 637)
@@ -645,4 +645,7 @@
 /^(?!(*:M)b)aZ/K
     aZbc


+/(?(DEFINE)(a))?b(?1)/
+    backgammon
+
 /-- End of testinput11 --/


Modified: code/trunk/testdata/testinput2
===================================================================
--- code/trunk/testdata/testinput2    2011-07-24 17:43:51 UTC (rev 636)
+++ code/trunk/testdata/testinput2    2011-07-24 17:44:12 UTC (rev 637)
@@ -2020,8 +2020,6 @@


/(?(DEFINE) abc) xyz/xI

-/(?(DEFINE) abc){3} xyz/x
-
 /(a|)*\d/
   \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
   \O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa4
@@ -3796,4 +3794,26 @@
     bazfooX\O8
     bazfooX\O10


+/(?=abc){3}abc/BZ
+
+/(?=abc)+abc/BZ
+
+/(?=abc)++abc/BZ
+
+/(?=abc){0}xyz/BZ
+
+/(?=(a))?./BZ
+
+/(?=(a))??./BZ
+
+/^(?=(a)){0}b(?1)/BZ
+
+/(?(DEFINE)(a))?b(?1)/BZ
+
+/^(?=(?1))?[az]([abc])d/BZ
+
+/^(?!a){0}\w+/BZ
+
+/(?<=(abc))?xyz/BZ
+
/-- End of testinput2 --/

Modified: code/trunk/testdata/testinput7
===================================================================
--- code/trunk/testdata/testinput7    2011-07-24 17:43:51 UTC (rev 636)
+++ code/trunk/testdata/testinput7    2011-07-24 17:44:12 UTC (rev 637)
@@ -4637,4 +4637,48 @@
      aaaa 
      bbb 


+/(?=abc){3}abc/+
+    abcabcabc
+    ** Failers
+    xyz  
+    
+/(?=abc)+abc/+
+    abcabcabc
+    ** Failers
+    xyz  
+    
+/(?=abc)++abc/+
+    abcabcabc
+    ** Failers
+    xyz  
+    
+/(?=abc){0}xyz/
+    xyz 
+
+/(?=abc){1}xyz/
+    ** Failers
+    xyz 
+    
+/(?=(a))?./
+    ab
+    bc
+      
+/(?=(a))??./
+    ab
+    bc
+
+/^(?=(a)){0}b(?1)/
+    backgammon
+
+/^(?=(?1))?[az]([abc])d/
+    abd 
+    zcdxx 
+
+/^(?!a){0}\w+/
+    aaaaa
+
+/(?<=(abc))?xyz/
+    abcxyz
+    pqrxyz 
+
 /-- End of testinput7 --/


Modified: code/trunk/testdata/testoutput1
===================================================================
--- code/trunk/testdata/testoutput1    2011-07-24 17:43:51 UTC (rev 636)
+++ code/trunk/testdata/testoutput1    2011-07-24 17:44:12 UTC (rev 637)
@@ -6855,4 +6855,77 @@
     aaaabc
  0: aaaabc


+/(?=abc){3}abc/+
+    abcabcabc
+ 0: abc
+ 0+ abcabc
+    ** Failers
+No match
+    xyz  
+No match
+    
+/(?=abc)+abc/+
+    abcabcabc
+ 0: abc
+ 0+ abcabc
+    ** Failers
+No match
+    xyz  
+No match
+    
+/(?=abc)++abc/+
+    abcabcabc
+ 0: abc
+ 0+ abcabc
+    ** Failers
+No match
+    xyz  
+No match
+    
+/(?=abc){0}xyz/
+    xyz 
+ 0: xyz
+
+/(?=abc){1}xyz/
+    ** Failers
+No match
+    xyz 
+No match
+    
+/(?=(a))?./
+    ab
+ 0: a
+ 1: a
+    bc
+ 0: b
+      
+/(?=(a))??./
+    ab
+ 0: a
+    bc
+ 0: b
+
+/^(?=(a)){0}b(?1)/
+    backgammon
+ 0: ba
+
+/^(?=(?1))?[az]([abc])d/
+    abd 
+ 0: abd
+ 1: b
+    zcdxx 
+ 0: zcd
+ 1: c
+
+/^(?!a){0}\w+/
+    aaaaa
+ 0: aaaaa
+
+/(?<=(abc))?xyz/
+    abcxyz
+ 0: xyz
+ 1: abc
+    pqrxyz 
+ 0: xyz
+
 /-- End of testinput1 --/


Modified: code/trunk/testdata/testoutput11
===================================================================
--- code/trunk/testdata/testoutput11    2011-07-24 17:43:51 UTC (rev 636)
+++ code/trunk/testdata/testoutput11    2011-07-24 17:44:12 UTC (rev 637)
@@ -1221,4 +1221,8 @@
     aZbc
  0: aZ


+/(?(DEFINE)(a))?b(?1)/
+    backgammon
+ 0: ba
+
 /-- End of testinput11 --/


Modified: code/trunk/testdata/testoutput2
===================================================================
--- code/trunk/testdata/testoutput2    2011-07-24 17:43:51 UTC (rev 636)
+++ code/trunk/testdata/testoutput2    2011-07-24 17:44:12 UTC (rev 637)
@@ -7944,9 +7944,6 @@
 First char = 'x'
 Need char = 'z'


-/(?(DEFINE) abc){3} xyz/x
-Failed: repeating a DEFINE group is not allowed at offset 17
-
/(a|)*\d/
\O0aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
No match
@@ -11985,4 +11982,153 @@
2: <unset>
3: <unset>

+/(?=abc){3}abc/BZ
+------------------------------------------------------------------
+        Bra
+        Assert
+        abc
+        Ket
+        abc
+        Ket
+        End
+------------------------------------------------------------------
+
+/(?=abc)+abc/BZ
+------------------------------------------------------------------
+        Bra
+        Assert
+        abc
+        Ket
+        abc
+        Ket
+        End
+------------------------------------------------------------------
+
+/(?=abc)++abc/BZ
+------------------------------------------------------------------
+        Bra
+        Assert
+        abc
+        Ket
+        abc
+        Ket
+        End
+------------------------------------------------------------------
+
+/(?=abc){0}xyz/BZ
+------------------------------------------------------------------
+        Bra
+        Skip zero
+        Assert
+        abc
+        Ket
+        xyz
+        Ket
+        End
+------------------------------------------------------------------
+
+/(?=(a))?./BZ
+------------------------------------------------------------------
+        Bra
+        Brazero
+        Assert
+        CBra 1
+        a
+        Ket
+        Ket
+        Any
+        Ket
+        End
+------------------------------------------------------------------
+
+/(?=(a))??./BZ
+------------------------------------------------------------------
+        Bra
+        Braminzero
+        Assert
+        CBra 1
+        a
+        Ket
+        Ket
+        Any
+        Ket
+        End
+------------------------------------------------------------------
+
+/^(?=(a)){0}b(?1)/BZ
+------------------------------------------------------------------
+        Bra
+        ^
+        Skip zero
+        Assert
+        CBra 1
+        a
+        Ket
+        Ket
+        b
+        Recurse
+        Ket
+        End
+------------------------------------------------------------------
+
+/(?(DEFINE)(a))?b(?1)/BZ
+------------------------------------------------------------------
+        Bra
+        Cond
+        Cond def
+        CBra 1
+        a
+        Ket
+        Ket
+        b
+        Recurse
+        Ket
+        End
+------------------------------------------------------------------
+
+/^(?=(?1))?[az]([abc])d/BZ
+------------------------------------------------------------------
+        Bra
+        ^
+        Brazero
+        Assert
+        Recurse
+        Ket
+        [az]
+        CBra 1
+        [a-c]
+        Ket
+        d
+        Ket
+        End
+------------------------------------------------------------------
+
+/^(?!a){0}\w+/BZ
+------------------------------------------------------------------
+        Bra
+        ^
+        Skip zero
+        Assert not
+        a
+        Ket
+        \w+
+        Ket
+        End
+------------------------------------------------------------------
+
+/(?<=(abc))?xyz/BZ
+------------------------------------------------------------------
+        Bra
+        Brazero
+        AssertB
+        Reverse
+        CBra 1
+        abc
+        Ket
+        Ket
+        xyz
+        Ket
+        End
+------------------------------------------------------------------
+
 /-- End of testinput2 --/


Modified: code/trunk/testdata/testoutput7
===================================================================
--- code/trunk/testdata/testoutput7    2011-07-24 17:43:51 UTC (rev 636)
+++ code/trunk/testdata/testoutput7    2011-07-24 17:44:12 UTC (rev 637)
@@ -7749,4 +7749,77 @@
      bbb 
 No match


+/(?=abc){3}abc/+
+    abcabcabc
+ 0: abc
+ 0+ abcabc
+    ** Failers
+No match
+    xyz  
+No match
+    
+/(?=abc)+abc/+
+    abcabcabc
+ 0: abc
+ 0+ abcabc
+    ** Failers
+No match
+    xyz  
+No match
+    
+/(?=abc)++abc/+
+    abcabcabc
+ 0: abc
+ 0+ abcabc
+    ** Failers
+No match
+    xyz  
+No match
+    
+/(?=abc){0}xyz/
+    xyz 
+ 0: xyz
+
+/(?=abc){1}xyz/
+    ** Failers
+No match
+    xyz 
+No match
+    
+/(?=(a))?./
+    ab
+ 0: a
+    bc
+ 0: b
+      
+/(?=(a))??./
+    ab
+ 0: a
+    bc
+ 0: b
+
+/^(?=(a)){0}b(?1)/
+    backgammon
+ 0: ba
+
+/^(?=(?1))?[az]([abc])d/
+    abd 
+ 0: abd
+    zcdxx 
+ 0: zcd
+
+/^(?!a){0}\w+/
+    aaaaa
+ 0: aaaaa
+ 1: aaaa
+ 2: aaa
+ 3: aa
+ 4: a
+
+/(?<=(abc))?xyz/
+    abcxyz
+ 0: xyz
+    pqrxyz 
+ 0: xyz
+
 /-- End of testinput7 --/