]> granicus.if.org Git - php/commitdiff
Added PCRE 3.01.
authorAndrei Zmievski <andrei@php.net>
Tue, 11 Apr 2000 17:36:06 +0000 (17:36 +0000)
committerAndrei Zmievski <andrei@php.net>
Tue, 11 Apr 2000 17:36:06 +0000 (17:36 +0000)
20 files changed:
ext/pcre/pcrelib/doc/Tech.Notes [new file with mode: 0644]
ext/pcre/pcrelib/doc/pcre.3 [new file with mode: 0644]
ext/pcre/pcrelib/doc/pcre.html [new file with mode: 0644]
ext/pcre/pcrelib/doc/pcre.txt [new file with mode: 0644]
ext/pcre/pcrelib/doc/pcreposix.3 [new file with mode: 0644]
ext/pcre/pcrelib/doc/pcreposix.html [new file with mode: 0644]
ext/pcre/pcrelib/doc/pcreposix.txt [new file with mode: 0644]
ext/pcre/pcrelib/doc/pcretest.txt [new file with mode: 0644]
ext/pcre/pcrelib/doc/perltest.txt [new file with mode: 0644]
ext/pcre/pcrelib/doc/pgrep.1 [new file with mode: 0644]
ext/pcre/pcrelib/doc/pgrep.html [new file with mode: 0644]
ext/pcre/pcrelib/doc/pgrep.txt [new file with mode: 0644]
ext/pcre/pcrelib/testdata/testinput1 [new file with mode: 0644]
ext/pcre/pcrelib/testdata/testinput2 [new file with mode: 0644]
ext/pcre/pcrelib/testdata/testinput3 [new file with mode: 0644]
ext/pcre/pcrelib/testdata/testinput4 [new file with mode: 0644]
ext/pcre/pcrelib/testdata/testoutput1 [new file with mode: 0644]
ext/pcre/pcrelib/testdata/testoutput2 [new file with mode: 0644]
ext/pcre/pcrelib/testdata/testoutput3 [new file with mode: 0644]
ext/pcre/pcrelib/testdata/testoutput4 [new file with mode: 0644]

diff --git a/ext/pcre/pcrelib/doc/Tech.Notes b/ext/pcre/pcrelib/doc/Tech.Notes
new file mode 100644 (file)
index 0000000..03904db
--- /dev/null
@@ -0,0 +1,242 @@
+Technical Notes about PCRE
+--------------------------
+
+Many years ago I implemented some regular expression functions to an algorithm
+suggested by Martin Richards. These were not Unix-like in form, and were quite
+restricted in what they could do by comparison with Perl. The interesting part
+about the algorithm was that the amount of space required to hold the compiled
+form of an expression was known in advance. The code to apply an expression did
+not operate by backtracking, as the Henry Spencer and Perl code does, but
+instead checked all possibilities simultaneously by keeping a list of current
+states and checking all of them as it advanced through the subject string. (In
+the terminology of Jeffrey Friedl's book, it was a "DFA algorithm".) When the
+pattern was all used up, all remaining states were possible matches, and the
+one matching the longest subset of the subject string was chosen. This did not
+necessarily maximize the individual wild portions of the pattern, as is
+expected in Unix and Perl-style regular expressions.
+
+By contrast, the code originally written by Henry Spencer and subsequently
+heavily modified for Perl actually compiles the expression twice: once in a
+dummy mode in order to find out how much store will be needed, and then for
+real. The execution function operates by backtracking and maximizing (or,
+optionally, minimizing in Perl) the amount of the subject that matches
+individual wild portions of the pattern. This is an "NFA algorithm" in Friedl's
+terminology.
+
+For the set of functions that forms PCRE (which are unrelated to those
+mentioned above), I tried at first to invent an algorithm that used an amount
+of store bounded by a multiple of the number of characters in the pattern, to
+save on compiling time. However, because of the greater complexity in Perl
+regular expressions, I couldn't do this. In any case, a first pass through the
+pattern is needed, in order to find internal flag settings like (?i) at top
+level. So PCRE works by running a very degenerate first pass to calculate a
+maximum store size, and then a second pass to do the real compile - which may
+use a bit less than the predicted amount of store. The idea is that this is
+going to turn out faster because the first pass is degenerate and the second
+pass can just store stuff straight into the vector. It does make the compiling
+functions bigger, of course, but they have got quite big anyway to handle all
+the Perl stuff.
+
+The compiled form of a pattern is a vector of bytes, containing items of
+variable length. The first byte in an item is an opcode, and the length of the
+item is either implicit in the opcode or contained in the data bytes which
+follow it. A list of all the opcodes follows:
+
+Opcodes with no following data
+------------------------------
+
+These items are all just one byte long
+
+  OP_END                 end of pattern
+  OP_ANY                 match any character
+  OP_SOD                 match start of data: \A
+  OP_CIRC                ^ (start of data, or after \n in multiline)
+  OP_NOT_WORD_BOUNDARY   \W
+  OP_WORD_BOUNDARY       \w
+  OP_NOT_DIGIT           \D
+  OP_DIGIT               \d
+  OP_NOT_WHITESPACE      \S
+  OP_WHITESPACE          \s
+  OP_NOT_WORDCHAR        \W
+  OP_WORDCHAR            \w
+  OP_EODN                match end of data or \n at end: \Z
+  OP_EOD                 match end of data: \z
+  OP_DOLL                $ (end of data, or before \n in multiline)
+  OP_RECURSE             match the pattern recursively
+
+
+Repeating single characters
+---------------------------
+
+The common repeats (*, +, ?) when applied to a single character appear as
+two-byte items using the following opcodes:
+
+  OP_STAR
+  OP_MINSTAR
+  OP_PLUS
+  OP_MINPLUS
+  OP_QUERY
+  OP_MINQUERY
+
+Those with "MIN" in their name are the minimizing versions. Each is followed by
+the character that is to be repeated. Other repeats make use of
+
+  OP_UPTO
+  OP_MINUPTO
+  OP_EXACT
+
+which are followed by a two-byte count (most significant first) and the
+repeated character. OP_UPTO matches from 0 to the given number. A repeat with a
+non-zero minimum and a fixed maximum is coded as an OP_EXACT followed by an
+OP_UPTO (or OP_MINUPTO).
+
+
+Repeating character types
+-------------------------
+
+Repeats of things like \d are done exactly as for single characters, except
+that instead of a character, the opcode for the type is stored in the data
+byte. The opcodes are:
+
+  OP_TYPESTAR
+  OP_TYPEMINSTAR
+  OP_TYPEPLUS
+  OP_TYPEMINPLUS
+  OP_TYPEQUERY
+  OP_TYPEMINQUERY
+  OP_TYPEUPTO
+  OP_TYPEMINUPTO
+  OP_TYPEEXACT
+
+
+Matching a character string
+---------------------------
+
+The OP_CHARS opcode is followed by a one-byte count and then that number of
+characters. If there are more than 255 characters in sequence, successive
+instances of OP_CHARS are used.
+
+
+Character classes
+-----------------
+
+OP_CLASS is used for a character class, provided there are at least two
+characters in the class. If there is only one character, OP_CHARS is used for a
+positive class, and OP_NOT for a negative one (that is, for something like
+[^a]). Another set of repeating opcodes (OP_NOTSTAR etc.) are used for a
+repeated, negated, single-character class. The normal ones (OP_STAR etc.) are
+used for a repeated positive single-character class.
+
+OP_CLASS is followed by a 32-byte bit map containing a 1 bit for every
+character that is acceptable. The bits are counted from the least significant
+end of each byte.
+
+
+Back references
+---------------
+
+OP_REF is followed by a single byte containing the reference number.
+
+
+Repeating character classes and back references
+-----------------------------------------------
+
+Single-character classes are handled specially (see above). This applies to
+OP_CLASS and OP_REF. In both cases, the repeat information follows the base
+item. The matching code looks at the following opcode to see if it is one of
+
+  OP_CRSTAR
+  OP_CRMINSTAR
+  OP_CRPLUS
+  OP_CRMINPLUS
+  OP_CRQUERY
+  OP_CRMINQUERY
+  OP_CRRANGE
+  OP_CRMINRANGE
+
+All but the last two are just single-byte items. The others are followed by
+four bytes of data, comprising the minimum and maximum repeat counts.
+
+
+Brackets and alternation
+------------------------
+
+A pair of non-capturing (round) brackets is wrapped round each expression at
+compile time, so alternation always happens in the context of brackets.
+Non-capturing brackets use the opcode OP_BRA, while capturing brackets use
+OP_BRA+1, OP_BRA+2, etc. [Note for North Americans: "bracket" to some English
+speakers, including myself, can be round, square, curly, or pointy. Hence this
+usage.]
+
+A bracket opcode is followed by two bytes which give the offset to the next
+alternative OP_ALT or, if there aren't any branches, to the matching KET
+opcode. Each OP_ALT is followed by two bytes giving the offset to the next one,
+or to the KET opcode.
+
+OP_KET is used for subpatterns that do not repeat indefinitely, while
+OP_KETRMIN and OP_KETRMAX are used for indefinite repetitions, minimally or
+maximally respectively. All three are followed by two bytes giving (as a
+positive number) the offset back to the matching BRA opcode.
+
+If a subpattern is quantified such that it is permitted to match zero times, it
+is preceded by one of OP_BRAZERO or OP_BRAMINZERO. These are single-byte
+opcodes which tell the matcher that skipping this subpattern entirely is a
+valid branch.
+
+A subpattern with an indefinite maximum repetition is replicated in the
+compiled data its minimum number of times (or once with a BRAZERO if the
+minimum is zero), with the final copy terminating with a KETRMIN or KETRMAX as
+appropriate.
+
+A subpattern with a bounded maximum repetition is replicated in a nested
+fashion up to the maximum number of times, with BRAZERO or BRAMINZERO before
+each replication after the minimum, so that, for example, (abc){2,5} is
+compiled as (abc)(abc)((abc)((abc)(abc)?)?)?. The 200-bracket limit does not
+apply to these internally generated brackets.
+
+
+Assertions
+----------
+
+Forward assertions are just like other subpatterns, but starting with one of
+the opcodes OP_ASSERT or OP_ASSERT_NOT. Backward assertions use the opcodes
+OP_ASSERTBACK and OP_ASSERTBACK_NOT, and the first opcode inside the assertion
+is OP_REVERSE, followed by a two byte count of the number of characters to move
+back the pointer in the subject string. A separate count is present in each
+alternative of a lookbehind assertion, allowing them to have different fixed
+lengths.
+
+
+Once-only subpatterns
+---------------------
+
+These are also just like other subpatterns, but they start with the opcode
+OP_ONCE.
+
+
+Conditional subpatterns
+-----------------------
+
+These are like other subpatterns, but they start with the opcode OP_COND. If
+the condition is a back reference, this is stored at the start of the
+subpattern using the opcode OP_CREF followed by one byte containing the
+reference number. Otherwise, a conditional subpattern will always start with
+one of the assertions.
+
+
+Changing options
+----------------
+
+If any of the /i, /m, or /s options are changed within a parenthesized group,
+an OP_OPT opcode is compiled, followed by one byte containing the new settings
+of these flags. If there are several alternatives in a group, there is an
+occurrence of OP_OPT at the start of all those following the first options
+change, to set appropriate options for the start of the alternative.
+Immediately after the end of the group there is another such item to reset the
+flags to their previous values. Other changes of flag within the pattern can be
+handled entirely at compile time, and so do not cause anything to be put into
+the compiled data.
+
+
+Philip Hazel
+February 2000
diff --git a/ext/pcre/pcrelib/doc/pcre.3 b/ext/pcre/pcrelib/doc/pcre.3
new file mode 100644 (file)
index 0000000..bd435e9
--- /dev/null
@@ -0,0 +1,1702 @@
+.TH PCRE 3
+.SH NAME
+pcre - Perl-compatible regular expressions.
+.SH SYNOPSIS
+.B #include <pcre.h>
+.PP
+.SM
+.br
+.B pcre *pcre_compile(const char *\fIpattern\fR, int \fIoptions\fR,
+.ti +5n
+.B const char **\fIerrptr\fR, int *\fIerroffset\fR,
+.ti +5n
+.B const unsigned char *\fItableptr\fR);
+.PP
+.br
+.B pcre_extra *pcre_study(const pcre *\fIcode\fR, int \fIoptions\fR,
+.ti +5n
+.B const char **\fIerrptr\fR);
+.PP
+.br
+.B int pcre_exec(const pcre *\fIcode\fR, "const pcre_extra *\fIextra\fR,"
+.ti +5n
+.B "const char *\fIsubject\fR," int \fIlength\fR, int \fIstartoffset\fR,
+.ti +5n
+.B int \fIoptions\fR, int *\fIovector\fR, int \fIovecsize\fR);
+.PP
+.br
+.B int pcre_copy_substring(const char *\fIsubject\fR, int *\fIovector\fR,
+.ti +5n
+.B int \fIstringcount\fR, int \fIstringnumber\fR, char *\fIbuffer\fR,
+.ti +5n
+.B int \fIbuffersize\fR);
+.PP
+.br
+.B int pcre_get_substring(const char *\fIsubject\fR, int *\fIovector\fR,
+.ti +5n
+.B int \fIstringcount\fR, int \fIstringnumber\fR,
+.ti +5n
+.B const char **\fIstringptr\fR);
+.PP
+.br
+.B int pcre_get_substring_list(const char *\fIsubject\fR,
+.ti +5n
+.B int *\fIovector\fR, int \fIstringcount\fR, "const char ***\fIlistptr\fR);"
+.PP
+.br
+.B const unsigned char *pcre_maketables(void);
+.PP
+.br
+.B int pcre_fullinfo(const pcre *\fIcode\fR, "const pcre_extra *\fIextra\fR,"
+.ti +5n
+.B int \fIwhat\fR, void *\fIwhere\fR);
+.PP
+.br
+.B int pcre_info(const pcre *\fIcode\fR, int *\fIoptptr\fR, int
+.B *\fIfirstcharptr\fR);
+.PP
+.br
+.B char *pcre_version(void);
+.PP
+.br
+.B void *(*pcre_malloc)(size_t);
+.PP
+.br
+.B void (*pcre_free)(void *);
+
+
+
+.SH DESCRIPTION
+The PCRE library is a set of functions that implement regular expression
+pattern matching using the same syntax and semantics as Perl 5, with just a few
+differences (see below). The current implementation corresponds to Perl 5.005,
+with some additional features from the Perl development release.
+
+PCRE has its own native API, which is described in this document. There is also
+a set of wrapper functions that correspond to the POSIX regular expression API.
+These are described in the \fBpcreposix\fR documentation.
+
+The native API function prototypes are defined in the header file \fBpcre.h\fR,
+and on Unix systems the library itself is called \fBlibpcre.a\fR, so can be
+accessed by adding \fB-lpcre\fR to the command for linking an application which
+calls it. The header file defines the macros PCRE_MAJOR and PCRE_MINOR to
+contain the major and minor release numbers for the library. Applications can
+use these to include support for different releases.
+
+The functions \fBpcre_compile()\fR, \fBpcre_study()\fR, and \fBpcre_exec()\fR
+are used for compiling and matching regular expressions, while
+\fBpcre_copy_substring()\fR, \fBpcre_get_substring()\fR, and
+\fBpcre_get_substring_list()\fR are convenience functions for extracting
+captured substrings from a matched subject string. The function
+\fBpcre_maketables()\fR is used (optionally) to build a set of character tables
+in the current locale for passing to \fBpcre_compile()\fR.
+
+The function \fBpcre_fullinfo()\fR is used to find out information about a
+compiled pattern; \fBpcre_info()\fR is an obsolete version which returns only
+some of the available information, but is retained for backwards compatibility.
+The function \fBpcre_version()\fR returns a pointer to a string containing the
+version of PCRE and its date of release.
+
+The global variables \fBpcre_malloc\fR and \fBpcre_free\fR initially contain
+the entry points of the standard \fBmalloc()\fR and \fBfree()\fR functions
+respectively. PCRE calls the memory management functions via these variables,
+so a calling program can replace them if it wishes to intercept the calls. This
+should be done before calling any PCRE functions.
+
+
+.SH MULTI-THREADING
+The PCRE functions can be used in multi-threading applications, with the
+proviso that the memory management functions pointed to by \fBpcre_malloc\fR
+and \fBpcre_free\fR are shared by all threads.
+
+The compiled form of a regular expression is not altered during matching, so
+the same compiled pattern can safely be used by several threads at once.
+
+
+.SH COMPILING A PATTERN
+The function \fBpcre_compile()\fR is called to compile a pattern into an
+internal form. The pattern is a C string terminated by a binary zero, and
+is passed in the argument \fIpattern\fR. A pointer to a single block of memory
+that is obtained via \fBpcre_malloc\fR is returned. This contains the
+compiled code and related data. The \fBpcre\fR type is defined for this for
+convenience, but in fact \fBpcre\fR is just a typedef for \fBvoid\fR, since the
+contents of the block are not externally defined. It is up to the caller to
+free the memory when it is no longer required.
+.PP
+The size of a compiled pattern is roughly proportional to the length of the
+pattern string, except that each character class (other than those containing
+just a single character, negated or not) requires 33 bytes, and repeat
+quantifiers with a minimum greater than one or a bounded maximum cause the
+relevant portions of the compiled pattern to be replicated.
+.PP
+The \fIoptions\fR argument contains independent bits that affect the
+compilation. It should be zero if no options are required. Some of the options,
+in particular, those that are compatible with Perl, can also be set and unset
+from within the pattern (see the detailed description of regular expressions
+below). For these options, the contents of the \fIoptions\fR argument specifies
+their initial settings at the start of compilation and execution. The
+PCRE_ANCHORED option can be set at the time of matching as well as at compile
+time.
+.PP
+If \fIerrptr\fR is NULL, \fBpcre_compile()\fR returns NULL immediately.
+Otherwise, if compilation of a pattern fails, \fBpcre_compile()\fR returns
+NULL, and sets the variable pointed to by \fIerrptr\fR to point to a textual
+error message. The offset from the start of the pattern to the character where
+the error was discovered is placed in the variable pointed to by
+\fIerroffset\fR, which must not be NULL. If it is, an immediate error is given.
+.PP
+If the final argument, \fItableptr\fR, is NULL, PCRE uses a default set of
+character tables which are built when it is compiled, using the default C
+locale. Otherwise, \fItableptr\fR must be the result of a call to
+\fBpcre_maketables()\fR. See the section on locale support below.
+.PP
+The following option bits are defined in the header file:
+
+  PCRE_ANCHORED
+
+If this bit is set, the pattern is forced to be "anchored", that is, it is
+constrained to match only at the start of the string which is being searched
+(the "subject string"). This effect can also be achieved by appropriate
+constructs in the pattern itself, which is the only way to do it in Perl.
+
+  PCRE_CASELESS
+
+If this bit is set, letters in the pattern match both upper and lower case
+letters. It is equivalent to Perl's /i option.
+
+  PCRE_DOLLAR_ENDONLY
+
+If this bit is set, a dollar metacharacter in the pattern matches only at the
+end of the subject string. Without this option, a dollar also matches
+immediately before the final character if it is a newline (but not before any
+other newlines). The PCRE_DOLLAR_ENDONLY option is ignored if PCRE_MULTILINE is
+set. There is no equivalent to this option in Perl.
+
+  PCRE_DOTALL
+
+If this bit is set, a dot metacharater in the pattern matches all characters,
+including newlines. Without it, newlines are excluded. This option is
+equivalent to Perl's /s option. A negative class such as [^a] always matches a
+newline character, independent of the setting of this option.
+
+  PCRE_EXTENDED
+
+If this bit is set, whitespace data characters in the pattern are totally
+ignored except when escaped or inside a character class, and characters between
+an unescaped # outside a character class and the next newline character,
+inclusive, are also ignored. This is equivalent to Perl's /x option, and makes
+it possible to include comments inside complicated patterns. Note, however,
+that this applies only to data characters. Whitespace characters may never
+appear within special character sequences in a pattern, for example within the
+sequence (?( which introduces a conditional subpattern.
+
+  PCRE_EXTRA
+
+This option was invented in order to turn on additional functionality of PCRE
+that is incompatible with Perl, but it is currently of very little use. When
+set, any backslash in a pattern that is followed by a letter that has no
+special meaning causes an error, thus reserving these combinations for future
+expansion. By default, as in Perl, a backslash followed by a letter with no
+special meaning is treated as a literal. There are at present no other features
+controlled by this option. It can also be set by a (?X) option setting within a
+pattern.
+
+  PCRE_MULTILINE
+
+By default, PCRE treats the subject string as consisting of a single "line" of
+characters (even if it actually contains several newlines). The "start of line"
+metacharacter (^) matches only at the start of the string, while the "end of
+line" metacharacter ($) matches only at the end of the string, or before a
+terminating newline (unless PCRE_DOLLAR_ENDONLY is set). This is the same as
+Perl.
+
+When PCRE_MULTILINE it is set, the "start of line" and "end of line" constructs
+match immediately following or immediately before any newline in the subject
+string, respectively, as well as at the very start and end. This is equivalent
+to Perl's /m option. If there are no "\\n" characters in a subject string, or
+no occurrences of ^ or $ in a pattern, setting PCRE_MULTILINE has no
+effect.
+
+  PCRE_UNGREEDY
+
+This option inverts the "greediness" of the quantifiers so that they are not
+greedy by default, but become greedy if followed by "?". It is not compatible
+with Perl. It can also be set by a (?U) option setting within the pattern.
+
+
+.SH STUDYING A PATTERN
+When a pattern is going to be used several times, it is worth spending more
+time analyzing it in order to speed up the time taken for matching. The
+function \fBpcre_study()\fR takes a pointer to a compiled pattern as its first
+argument, and returns a pointer to a \fBpcre_extra\fR block (another \fBvoid\fR
+typedef) containing additional information about the pattern; this can be
+passed to \fBpcre_exec()\fR. If no additional information is available, NULL
+is returned.
+
+The second argument contains option bits. At present, no options are defined
+for \fBpcre_study()\fR, and this argument should always be zero.
+
+The third argument for \fBpcre_study()\fR is a pointer to an error message. If
+studying succeeds (even if no data is returned), the variable it points to is
+set to NULL. Otherwise it points to a textual error message.
+
+At present, studying a pattern is useful only for non-anchored patterns that do
+not have a single fixed starting character. A bitmap of possible starting
+characters is created.
+
+
+.SH LOCALE SUPPORT
+PCRE handles caseless matching, and determines whether characters are letters,
+digits, or whatever, by reference to a set of tables. The library contains a
+default set of tables which is created in the default C locale when PCRE is
+compiled. This is used when the final argument of \fBpcre_compile()\fR is NULL,
+and is sufficient for many applications.
+
+An alternative set of tables can, however, be supplied. Such tables are built
+by calling the \fBpcre_maketables()\fR function, which has no arguments, in the
+relevant locale. The result can then be passed to \fBpcre_compile()\fR as often
+as necessary. For example, to build and use tables that are appropriate for the
+French locale (where accented characters with codes greater than 128 are
+treated as letters), the following code could be used:
+
+  setlocale(LC_CTYPE, "fr");
+  tables = pcre_maketables();
+  re = pcre_compile(..., tables);
+
+The tables are built in memory that is obtained via \fBpcre_malloc\fR. The
+pointer that is passed to \fBpcre_compile\fR is saved with the compiled
+pattern, and the same tables are used via this pointer by \fBpcre_study()\fR
+and \fBpcre_exec()\fR. Thus for any single pattern, compilation, studying and
+matching all happen in the same locale, but different patterns can be compiled
+in different locales. It is the caller's responsibility to ensure that the
+memory containing the tables remains available for as long as it is needed.
+
+
+.SH INFORMATION ABOUT A PATTERN
+The \fBpcre_fullinfo()\fR function returns information about a compiled
+pattern. It replaces the obsolete \fBpcre_info()\fR function, which is
+nevertheless retained for backwards compability (and is documented below).
+
+The first argument for \fBpcre_fullinfo()\fR is a pointer to the compiled
+pattern. The second argument is the result of \fBpcre_study()\fR, or NULL if
+the pattern was not studied. The third argument specifies which piece of
+information is required, while the fourth argument is a pointer to a variable
+to receive the data. The yield of the function is zero for success, or one of
+the following negative numbers:
+
+  PCRE_ERROR_NULL       the argument \fIcode\fR was NULL
+                        the argument \fIwhere\fR was NULL
+  PCRE_ERROR_BADMAGIC   the "magic number" was not found
+  PCRE_ERROR_BADOPTION  the value of \fIwhat\fR was invalid
+
+The possible values for the third argument are defined in \fBpcre.h\fR, and are
+as follows:
+
+  PCRE_INFO_OPTIONS
+
+Return a copy of the options with which the pattern was compiled. The fourth
+argument should point to au \fBunsigned long int\fR variable. These option bits
+are those specified in the call to \fBpcre_compile()\fR, modified by any
+top-level option settings within the pattern itself, and with the PCRE_ANCHORED
+bit forcibly set if the form of the pattern implies that it can match only at
+the start of a subject string.
+
+  PCRE_INFO_SIZE
+
+Return the size of the compiled pattern, that is, the value that was passed as
+the argument to \fBpcre_malloc()\fR when PCRE was getting memory in which to
+place the compiled data. The fourth argument should point to a \fBsize_t\fR
+variable.
+
+  PCRE_INFO_CAPTURECOUNT
+
+Return the number of capturing subpatterns in the pattern. The fourth argument
+should point to an \fbint\fR variable.
+
+  PCRE_INFO_BACKREFMAX
+
+Return the number of the highest back reference in the pattern. The fourth
+argument should point to an \fBint\fR variable. Zero is returned if there are
+no back references.
+
+  PCRE_INFO_FIRSTCHAR
+
+Return information about the first character of any matched string, for a
+non-anchored pattern. If there is a fixed first character, e.g. from a pattern
+such as (cat|cow|coyote), then it is returned in the integer pointed to by
+\fIwhere\fR. Otherwise, if either
+
+(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch
+starts with "^", or
+
+(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set
+(if it were set, the pattern would be anchored),
+
+then -1 is returned, indicating that the pattern matches only at the
+start of a subject string or after any "\\n" within the string. Otherwise -2 is
+returned. For anchored patterns, -2 is returned.
+
+  PCRE_INFO_FIRSTTABLE
+
+If the pattern was studied, and this resulted in the construction of a 256-bit
+table indicating a fixed set of characters for the first character in any
+matching string, a pointer to the table is returned. Otherwise NULL is
+returned. The fourth argument should point to an \fBunsigned char *\fR
+variable.
+
+  PCRE_INFO_LASTLITERAL
+
+For a non-anchored pattern, return the value of the rightmost literal character
+which must exist in any matched string, other than at its start. The fourth
+argument should point to an \fBint\fR variable. If there is no such character,
+or if the pattern is anchored, -1 is returned. For example, for the pattern
+/a\\d+z\\d+/ the returned value is 'z'.
+
+The \fBpcre_info()\fR function is now obsolete because its interface is too
+restrictive to return all the available data about a compiled pattern. New
+programs should use \fBpcre_fullinfo()\fR instead. The yield of
+\fBpcre_info()\fR is the number of capturing subpatterns, or one of the
+following negative numbers:
+
+  PCRE_ERROR_NULL       the argument \fIcode\fR was NULL
+  PCRE_ERROR_BADMAGIC   the "magic number" was not found
+
+If the \fIoptptr\fR argument is not NULL, a copy of the options with which the
+pattern was compiled is placed in the integer it points to (see
+PCRE_INFO_OPTIONS above).
+
+If the pattern is not anchored and the \fIfirstcharptr\fR argument is not NULL,
+it is used to pass back information about the first character of any matched
+string (see PCRE_INFO_FIRSTCHAR above).
+
+
+.SH MATCHING A PATTERN
+The function \fBpcre_exec()\fR is called to match a subject string against a
+pre-compiled pattern, which is passed in the \fIcode\fR argument. If the
+pattern has been studied, the result of the study should be passed in the
+\fIextra\fR argument. Otherwise this must be NULL.
+
+The PCRE_ANCHORED option can be passed in the \fIoptions\fR argument, whose
+unused bits must be zero. However, if a pattern was compiled with
+PCRE_ANCHORED, or turned out to be anchored by virtue of its contents, it
+cannot be made unachored at matching time.
+
+There are also three further options that can be set only at matching time:
+
+  PCRE_NOTBOL
+
+The first character of the string is not the beginning of a line, so the
+circumflex metacharacter should not match before it. Setting this without
+PCRE_MULTILINE (at compile time) causes circumflex never to match.
+
+  PCRE_NOTEOL
+
+The end of the string is not the end of a line, so the dollar metacharacter
+should not match it nor (except in multiline mode) a newline immediately before
+it. Setting this without PCRE_MULTILINE (at compile time) causes dollar never
+to match.
+
+  PCRE_NOTEMPTY
+
+An empty string is not considered to be a valid match if this option is set. If
+there are alternatives in the pattern, they are tried. If all the alternatives
+match the empty string, the entire match fails. For example, if the pattern
+
+  a?b?
+
+is applied to a string not beginning with "a" or "b", it matches the empty
+string at the start of the subject. With PCRE_NOTEMPTY set, this match is not
+valid, so PCRE searches further into the string for occurrences of "a" or "b".
+
+Perl has no direct equivalent of PCRE_NOTEMPTY, but it does make a special case
+of a pattern match of the empty string within its \fBsplit()\fR function, and
+when using the /g modifier. It is possible to emulate Perl's behaviour after
+matching a null string by first trying the match again at the same offset with
+PCRE_NOTEMPTY set, and then if that fails by advancing the starting offset (see
+below) and trying an ordinary match again.
+
+The subject string is passed as a pointer in \fIsubject\fR, a length in
+\fIlength\fR, and a starting offset in \fIstartoffset\fR. Unlike the pattern
+string, it may contain binary zero characters. When the starting offset is
+zero, the search for a match starts at the beginning of the subject, and this
+is by far the most common case.
+
+A non-zero starting offset is useful when searching for another match in the
+same subject by calling \fBpcre_exec()\fR again after a previous success.
+Setting \fIstartoffset\fR differs from just passing over a shortened string and
+setting PCRE_NOTBOL in the case of a pattern that begins with any kind of
+lookbehind. For example, consider the pattern
+
+  \\Biss\\B
+
+which finds occurrences of "iss" in the middle of words. (\\B matches only if
+the current position in the subject is not a word boundary.) When applied to
+the string "Mississipi" the first call to \fBpcre_exec()\fR finds the first
+occurrence. If \fBpcre_exec()\fR is called again with just the remainder of the
+subject, namely "issipi", it does not match, because \\B is always false at the
+start of the subject, which is deemed to be a word boundary. However, if
+\fBpcre_exec()\fR is passed the entire string again, but with \fIstartoffset\fR
+set to 4, it finds the second occurrence of "iss" because it is able to look
+behind the starting point to discover that it is preceded by a letter.
+
+If a non-zero starting offset is passed when the pattern is anchored, one
+attempt to match at the given offset is tried. This can only succeed if the
+pattern does not require the match to be at the start of the subject.
+
+In general, a pattern matches a certain portion of the subject, and in
+addition, further substrings from the subject may be picked out by parts of the
+pattern. Following the usage in Jeffrey Friedl's book, this is called
+"capturing" in what follows, and the phrase "capturing subpattern" is used for
+a fragment of a pattern that picks out a substring. PCRE supports several other
+kinds of parenthesized subpattern that do not cause substrings to be captured.
+
+Captured substrings are returned to the caller via a vector of integer offsets
+whose address is passed in \fIovector\fR. The number of elements in the vector
+is passed in \fIovecsize\fR. The first two-thirds of the vector is used to pass
+back captured substrings, each substring using a pair of integers. The
+remaining third of the vector is used as workspace by \fBpcre_exec()\fR while
+matching capturing subpatterns, and is not available for passing back
+information. The length passed in \fIovecsize\fR should always be a multiple of
+three. If it is not, it is rounded down.
+
+When a match has been successful, information about captured substrings is
+returned in pairs of integers, starting at the beginning of \fIovector\fR, and
+continuing up to two-thirds of its length at the most. The first element of a
+pair is set to the offset of the first character in a substring, and the second
+is set to the offset of the first character after the end of a substring. The
+first pair, \fIovector[0]\fR and \fIovector[1]\fR, identify the portion of the
+subject string matched by the entire pattern. The next pair is used for the
+first capturing subpattern, and so on. The value returned by \fBpcre_exec()\fR
+is the number of pairs that have been set. If there are no capturing
+subpatterns, the return value from a successful match is 1, indicating that
+just the first pair of offsets has been set.
+
+Some convenience functions are provided for extracting the captured substrings
+as separate strings. These are described in the following section.
+
+It is possible for an capturing subpattern number \fIn+1\fR to match some
+part of the subject when subpattern \fIn\fR has not been used at all. For
+example, if the string "abc" is matched against the pattern (a|(z))(bc)
+subpatterns 1 and 3 are matched, but 2 is not. When this happens, both offset
+values corresponding to the unused subpattern are set to -1.
+
+If a capturing subpattern is matched repeatedly, it is the last portion of the
+string that it matched that gets returned.
+
+If the vector is too small to hold all the captured substrings, it is used as
+far as possible (up to two-thirds of its length), and the function returns a
+value of zero. In particular, if the substring offsets are not of interest,
+\fBpcre_exec()\fR may be called with \fIovector\fR passed as NULL and
+\fIovecsize\fR as zero. However, if the pattern contains back references and
+the \fIovector\fR isn't big enough to remember the related substrings, PCRE has
+to get additional memory for use during matching. Thus it is usually advisable
+to supply an \fIovector\fR.
+
+Note that \fBpcre_info()\fR can be used to find out how many capturing
+subpatterns there are in a compiled pattern. The smallest size for
+\fIovector\fR that will allow for \fIn\fR captured substrings in addition to
+the offsets of the substring matched by the whole pattern is (\fIn\fR+1)*3.
+
+If \fBpcre_exec()\fR fails, it returns a negative number. The following are
+defined in the header file:
+
+  PCRE_ERROR_NOMATCH        (-1)
+
+The subject string did not match the pattern.
+
+  PCRE_ERROR_NULL           (-2)
+
+Either \fIcode\fR or \fIsubject\fR was passed as NULL, or \fIovector\fR was
+NULL and \fIovecsize\fR was not zero.
+
+  PCRE_ERROR_BADOPTION      (-3)
+
+An unrecognized bit was set in the \fIoptions\fR argument.
+
+  PCRE_ERROR_BADMAGIC       (-4)
+
+PCRE stores a 4-byte "magic number" at the start of the compiled code, to catch
+the case when it is passed a junk pointer. This is the error it gives when the
+magic number isn't present.
+
+  PCRE_ERROR_UNKNOWN_NODE   (-5)
+
+While running the pattern match, an unknown item was encountered in the
+compiled pattern. This error could be caused by a bug in PCRE or by overwriting
+of the compiled pattern.
+
+  PCRE_ERROR_NOMEMORY       (-6)
+
+If a pattern contains back references, but the \fIovector\fR that is passed to
+\fBpcre_exec()\fR is not big enough to remember the referenced substrings, PCRE
+gets a block of memory at the start of matching to use for this purpose. If the
+call via \fBpcre_malloc()\fR fails, this error is given. The memory is freed at
+the end of matching.
+
+
+.SH EXTRACTING CAPTURED SUBSTRINGS
+Captured substrings can be accessed directly by using the offsets returned by
+\fBpcre_exec()\fR in \fIovector\fR. For convenience, the functions
+\fBpcre_copy_substring()\fR, \fBpcre_get_substring()\fR, and
+\fBpcre_get_substring_list()\fR are provided for extracting captured substrings
+as new, separate, zero-terminated strings. A substring that contains a binary
+zero is correctly extracted and has a further zero added on the end, but the
+result does not, of course, function as a C string.
+
+The first three arguments are the same for all three functions: \fIsubject\fR
+is the subject string which has just been successfully matched, \fIovector\fR
+is a pointer to the vector of integer offsets that was passed to
+\fBpcre_exec()\fR, and \fIstringcount\fR is the number of substrings that
+were captured by the match, including the substring that matched the entire
+regular expression. This is the value returned by \fBpcre_exec\fR if it
+is greater than zero. If \fBpcre_exec()\fR returned zero, indicating that it
+ran out of space in \fIovector\fR, then the value passed as
+\fIstringcount\fR should be the size of the vector divided by three.
+
+The functions \fBpcre_copy_substring()\fR and \fBpcre_get_substring()\fR
+extract a single substring, whose number is given as \fIstringnumber\fR. A
+value of zero extracts the substring that matched the entire pattern, while
+higher values extract the captured substrings. For \fBpcre_copy_substring()\fR,
+the string is placed in \fIbuffer\fR, whose length is given by
+\fIbuffersize\fR, while for \fBpcre_get_substring()\fR a new block of store is
+obtained via \fBpcre_malloc\fR, and its address is returned via
+\fIstringptr\fR. The yield of the function is the length of the string, not
+including the terminating zero, or one of
+
+  PCRE_ERROR_NOMEMORY       (-6)
+
+The buffer was too small for \fBpcre_copy_substring()\fR, or the attempt to get
+memory failed for \fBpcre_get_substring()\fR.
+
+  PCRE_ERROR_NOSUBSTRING    (-7)
+
+There is no substring whose number is \fIstringnumber\fR.
+
+The \fBpcre_get_substring_list()\fR function extracts all available substrings
+and builds a list of pointers to them. All this is done in a single block of
+memory which is obtained via \fBpcre_malloc\fR. The address of the memory block
+is returned via \fIlistptr\fR, which is also the start of the list of string
+pointers. The end of the list is marked by a NULL pointer. The yield of the
+function is zero if all went well, or
+
+  PCRE_ERROR_NOMEMORY       (-6)
+
+if the attempt to get the memory block failed.
+
+When any of these functions encounter a substring that is unset, which can
+happen when capturing subpattern number \fIn+1\fR matches some part of the
+subject, but subpattern \fIn\fR has not been used at all, they return an empty
+string. This can be distinguished from a genuine zero-length substring by
+inspecting the appropriate offset in \fIovector\fR, which is negative for unset
+substrings.
+
+
+
+.SH LIMITATIONS
+There are some size limitations in PCRE but it is hoped that they will never in
+practice be relevant.
+The maximum length of a compiled pattern is 65539 (sic) bytes.
+All values in repeating quantifiers must be less than 65536.
+The maximum number of capturing subpatterns is 99.
+The maximum number of all parenthesized subpatterns, including capturing
+subpatterns, assertions, and other types of subpattern, is 200.
+
+The maximum length of a subject string is the largest positive number that an
+integer variable can hold. However, PCRE uses recursion to handle subpatterns
+and indefinite repetition. This means that the available stack space may limit
+the size of a subject string that can be processed by certain patterns.
+
+
+.SH DIFFERENCES FROM PERL
+The differences described here are with respect to Perl 5.005.
+
+1. By default, a whitespace character is any character that the C library
+function \fBisspace()\fR recognizes, though it is possible to compile PCRE with
+alternative character type tables. Normally \fBisspace()\fR matches space,
+formfeed, newline, carriage return, horizontal tab, and vertical tab. Perl 5
+no longer includes vertical tab in its set of whitespace characters. The \\v
+escape that was in the Perl documentation for a long time was never in fact
+recognized. However, the character itself was treated as whitespace at least
+up to 5.002. In 5.004 and 5.005 it does not match \\s.
+
+2. PCRE does not allow repeat quantifiers on lookahead 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.
+
+3. Capturing subpatterns that occur inside negative lookahead assertions are
+counted, but their entries in the offsets vector are never set. Perl sets its
+numerical variables from any such patterns that are matched before the
+assertion fails to match something (thereby succeeding), but only if the
+negative lookahead assertion contains just one branch.
+
+4. Though binary zero characters are supported in the subject string, they are
+not allowed in a pattern string because it is passed as a normal C string,
+terminated by zero. The escape sequence "\\0" can be used in the pattern to
+represent a binary zero.
+
+5. The following Perl escape sequences are not supported: \\l, \\u, \\L, \\U,
+\\E, \\Q. In fact these are implemented by Perl's general string-handling and
+are not part of its pattern matching engine.
+
+6. The Perl \\G assertion is not supported as it is not relevant to single
+pattern matches.
+
+7. Fairly obviously, PCRE does not support the (?{code}) and (?p{code})
+constructions. However, there is some experimental support for recursive
+patterns using the non-Perl item (?R).
+
+8. There are at the time of writing some oddities in Perl 5.005_02 concerned
+with the settings of captured strings when part of a pattern is repeated. For
+example, matching "aba" against the pattern /^(a(b)?)+$/ sets $2 to the value
+"b", but matching "aabbaa" against /^(aa(bb)?)+$/ leaves $2 unset. However, if
+the pattern is changed to /^(aa(b(b))?)+$/ then $2 (and $3) get set.
+
+In Perl 5.004 $2 is set in both cases, and that is also true of PCRE. If in the
+future Perl changes to a consistent state that is different, PCRE may change to
+follow.
+
+9. Another as yet unresolved discrepancy is that in Perl 5.005_02 the pattern
+/^(a)?(?(1)a|b)+$/ matches the string "a", whereas in PCRE it does not.
+However, in both Perl and PCRE /^(a)?a/ matched against "a" leaves $1 unset.
+
+10. PCRE provides some extensions to the Perl regular expression facilities:
+
+(a) Although lookbehind assertions must match fixed length strings, each
+alternative branch of a lookbehind assertion can match a different length of
+string. Perl 5.005 requires them all to have the same length.
+
+(b) If PCRE_DOLLAR_ENDONLY is set and PCRE_MULTILINE is not set, the $ meta-
+character matches only at the very end of the string.
+
+(c) If PCRE_EXTRA is set, a backslash followed by a letter with no special
+meaning is faulted.
+
+(d) If PCRE_UNGREEDY is set, the greediness of the repetition quantifiers is
+inverted, that is, by default they are not greedy, but if followed by a
+question mark they are.
+
+(e) PCRE_ANCHORED can be used to force a pattern to be tried only at the start
+of the subject.
+
+(f) The PCRE_NOTBOL, PCRE_NOTEOL, and PCRE_NOTEMPTY options for
+\fBpcre_exec()\fR have no Perl equivalents.
+
+(g) The (?R) construct allows for recursive pattern matching (Perl 5.6 can do
+this using the (?p{code}) construct, which PCRE cannot of course support.)
+
+
+.SH REGULAR EXPRESSION DETAILS
+The syntax and semantics of the regular expressions supported by PCRE are
+described below. Regular expressions are also described in the Perl
+documentation and in a number of other books, some of which have copious
+examples. Jeffrey Friedl's "Mastering Regular Expressions", published by
+O'Reilly (ISBN 1-56592-257), covers them in great detail. The description
+here is intended as reference documentation.
+
+A regular expression is a pattern that is matched against a subject string from
+left to right. Most characters stand for themselves in a pattern, and match the
+corresponding characters in the subject. As a trivial example, the pattern
+
+  The quick brown fox
+
+matches a portion of a subject string that is identical to itself. The power of
+regular expressions comes from the ability to include alternatives and
+repetitions in the pattern. These are encoded in the pattern by the use of
+\fImeta-characters\fR, which do not stand for themselves but instead are
+interpreted in some special way.
+
+There are two different sets of meta-characters: those that are recognized
+anywhere in the pattern except within square brackets, and those that are
+recognized in square brackets. Outside square brackets, the meta-characters are
+as follows:
+
+  \\      general escape character with several uses
+  ^      assert start of subject (or line, in multiline mode)
+  $      assert end of subject (or line, in multiline mode)
+  .      match any character except newline (by default)
+  [      start character class definition
+  |      start of alternative branch
+  (      start subpattern
+  )      end subpattern
+  ?      extends the meaning of (
+         also 0 or 1 quantifier
+         also quantifier minimizer
+  *      0 or more quantifier
+  +      1 or more quantifier
+  {      start min/max quantifier
+
+Part of a pattern that is in square brackets is called a "character class". In
+a character class the only meta-characters are:
+
+  \\      general escape character
+  ^      negate the class, but only if the first character
+  -      indicates character range
+  ]      terminates the character class
+
+The following sections describe the use of each of the meta-characters.
+
+
+.SH BACKSLASH
+The backslash character has several uses. Firstly, if it is followed by a
+non-alphameric character, it takes away any special meaning that character may
+have. This use of backslash as an escape character applies both inside and
+outside character classes.
+
+For example, if you want to match a "*" character, you write "\\*" in the
+pattern. This applies whether or not the following character would otherwise be
+interpreted as a meta-character, so it is always safe to precede a
+non-alphameric with "\\" to specify that it stands for itself. In particular,
+if you want to match a backslash, you write "\\\\".
+
+If a pattern is compiled with the PCRE_EXTENDED option, whitespace in the
+pattern (other than in a character class) and characters between a "#" outside
+a character class and the next newline character are ignored. An escaping
+backslash can be used to include a whitespace or "#" character as part of the
+pattern.
+
+A second use of backslash provides a way of encoding non-printing characters
+in patterns in a visible manner. There is no restriction on the appearance of
+non-printing characters, apart from the binary zero that terminates a pattern,
+but when a pattern is being prepared by text editing, it is usually easier to
+use one of the following escape sequences than the binary character it
+represents:
+
+  \\a     alarm, that is, the BEL character (hex 07)
+  \\cx    "control-x", where x is any character
+  \\e     escape (hex 1B)
+  \\f     formfeed (hex 0C)
+  \\n     newline (hex 0A)
+  \\r     carriage return (hex 0D)
+  \\t     tab (hex 09)
+  \\xhh   character with hex code hh
+  \\ddd   character with octal code ddd, or backreference
+
+The precise effect of "\\cx" is as follows: if "x" is a lower case letter, it
+is converted to upper case. Then bit 6 of the character (hex 40) is inverted.
+Thus "\\cz" becomes hex 1A, but "\\c{" becomes hex 3B, while "\\c;" becomes hex
+7B.
+
+After "\\x", up to two hexadecimal digits are read (letters can be in upper or
+lower case).
+
+After "\\0" up to two further octal digits are read. In both cases, if there
+are fewer than two digits, just those that are present are used. Thus the
+sequence "\\0\\x\\07" specifies two binary zeros followed by a BEL character.
+Make sure you supply two digits after the initial zero if the character that
+follows is itself an octal digit.
+
+The handling of a backslash followed by a digit other than 0 is complicated.
+Outside a character class, PCRE reads it and any following digits as a decimal
+number. If the number is less than 10, or if there have been at least that many
+previous capturing left parentheses in the expression, the entire sequence is
+taken as a \fIback reference\fR. A description of how this works is given
+later, following the discussion of parenthesized subpatterns.
+
+Inside a character class, or if the decimal number is greater than 9 and there
+have not been that many capturing subpatterns, PCRE re-reads up to three octal
+digits following the backslash, and generates a single byte from the least
+significant 8 bits of the value. Any subsequent digits stand for themselves.
+For example:
+
+  \\040   is another way of writing a space
+  \\40    is the same, provided there are fewer than 40
+            previous capturing subpatterns
+  \\7     is always a back reference
+  \\11    might be a back reference, or another way of
+            writing a tab
+  \\011   is always a tab
+  \\0113  is a tab followed by the character "3"
+  \\113   is the character with octal code 113 (since there
+            can be no more than 99 back references)
+  \\377   is a byte consisting entirely of 1 bits
+  \\81    is either a back reference, or a binary zero
+            followed by the two characters "8" and "1"
+
+Note that octal values of 100 or greater must not be introduced by a leading
+zero, because no more than three octal digits are ever read.
+
+All the sequences that define a single byte value can be used both inside and
+outside character classes. In addition, inside a character class, the sequence
+"\\b" is interpreted as the backspace character (hex 08). Outside a character
+class it has a different meaning (see below).
+
+The third use of backslash is for specifying generic character types:
+
+  \\d     any decimal digit
+  \\D     any character that is not a decimal digit
+  \\s     any whitespace character
+  \\S     any character that is not a whitespace character
+  \\w     any "word" character
+  \\W     any "non-word" character
+
+Each pair of escape sequences partitions the complete set of characters into
+two disjoint sets. Any given character matches one, and only one, of each pair.
+
+A "word" character is any letter or digit or the underscore character, that is,
+any character which can be part of a Perl "word". The definition of letters and
+digits is controlled by PCRE's character tables, and may vary if locale-
+specific matching is taking place (see "Locale support" above). For example, in
+the "fr" (French) locale, some character codes greater than 128 are used for
+accented letters, and these are matched by \\w.
+
+These character type sequences can appear both inside and outside character
+classes. They each match one character of the appropriate type. If the current
+matching point is at the end of the subject string, all of them fail, since
+there is no character to match.
+
+The fourth use of backslash is for certain simple assertions. An assertion
+specifies a condition that has to be met at a particular point in a match,
+without consuming any characters from the subject string. The use of
+subpatterns for more complicated assertions is described below. The backslashed
+assertions are
+
+  \\b     word boundary
+  \\B     not a word boundary
+  \\A     start of subject (independent of multiline mode)
+  \\Z     end of subject or newline at end (independent of multiline mode)
+  \\z     end of subject (independent of multiline mode)
+
+These assertions may not appear in character classes (but note that "\\b" has a
+different meaning, namely the backspace character, inside a character class).
+
+A word boundary is a position in the subject string where the current character
+and the previous character do not both match \\w or \\W (i.e. one matches
+\\w and the other matches \\W), or the start or end of the string if the
+first or last character matches \\w, respectively.
+
+The \\A, \\Z, and \\z assertions differ from the traditional circumflex and
+dollar (described below) in that they only ever match at the very start and end
+of the subject string, whatever options are set. They are not affected by the
+PCRE_NOTBOL or PCRE_NOTEOL options. If the \fIstartoffset\fR argument of
+\fBpcre_exec()\fR is non-zero, \\A can never match. The difference between \\Z
+and \\z is that \\Z matches before a newline that is the last character of the
+string as well as at the end of the string, whereas \\z matches only at the
+end.
+
+
+.SH CIRCUMFLEX AND DOLLAR
+Outside a character class, in the default matching mode, the circumflex
+character is an assertion which is true only if the current matching point is
+at the start of the subject string. If the \fIstartoffset\fR argument of
+\fBpcre_exec()\fR is non-zero, circumflex can never match. Inside a character
+class, circumflex has an entirely different meaning (see below).
+
+Circumflex need not be the first character of the pattern if a number of
+alternatives are involved, but it should be the first thing in each alternative
+in which it appears if the pattern is ever to match that branch. If all
+possible alternatives start with a circumflex, that is, if the pattern is
+constrained to match only at the start of the subject, it is said to be an
+"anchored" pattern. (There are also other constructs that can cause a pattern
+to be anchored.)
+
+A dollar character is an assertion which is true only if the current matching
+point is at the end of the subject string, or immediately before a newline
+character that is the last character in the string (by default). Dollar need
+not be the last character of the pattern if a number of alternatives are
+involved, but it should be the last item in any branch in which it appears.
+Dollar has no special meaning in a character class.
+
+The meaning of dollar can be changed so that it matches only at the very end of
+the string, by setting the PCRE_DOLLAR_ENDONLY option at compile or matching
+time. This does not affect the \\Z assertion.
+
+The meanings of the circumflex and dollar characters are changed if the
+PCRE_MULTILINE option is set. When this is the case, they match immediately
+after and immediately before an internal "\\n" character, respectively, in
+addition to matching at the start and end of the subject string. For example,
+the pattern /^abc$/ matches the subject string "def\\nabc" in multiline mode,
+but not otherwise. Consequently, patterns that are anchored in single line mode
+because all branches start with "^" are not anchored in multiline mode, and a
+match for circumflex is possible when the \fIstartoffset\fR argument of
+\fBpcre_exec()\fR is non-zero. The PCRE_DOLLAR_ENDONLY option is ignored if
+PCRE_MULTILINE is set.
+
+Note that the sequences \\A, \\Z, and \\z can be used to match the start and
+end of the subject in both modes, and if all branches of a pattern start with
+\\A is it always anchored, whether PCRE_MULTILINE is set or not.
+
+
+.SH FULL STOP (PERIOD, DOT)
+Outside a character class, a dot in the pattern matches any one character in
+the subject, including a non-printing character, but not (by default) newline.
+If the PCRE_DOTALL option is set, then dots match newlines as well. The
+handling of dot is entirely independent of the handling of circumflex and
+dollar, the only relationship being that they both involve newline characters.
+Dot has no special meaning in a character class.
+
+
+.SH SQUARE BRACKETS
+An opening square bracket introduces a character class, terminated by a closing
+square bracket. A closing square bracket on its own is not special. If a
+closing square bracket is required as a member of the class, it should be the
+first data character in the class (after an initial circumflex, if present) or
+escaped with a backslash.
+
+A character class matches a single character in the subject; the character must
+be in the set of characters defined by the class, unless the first character in
+the class is a circumflex, in which case the subject character must not be in
+the set defined by the class. If a circumflex is actually required as a member
+of the class, ensure it is not the first character, or escape it with a
+backslash.
+
+For example, the character class [aeiou] matches any lower case vowel, while
+[^aeiou] matches any character that is not a lower case vowel. Note that a
+circumflex is just a convenient notation for specifying the characters which
+are in the class by enumerating those that are not. It is not an assertion: it
+still consumes a character from the subject string, and fails if the current
+pointer is at the end of the string.
+
+When caseless matching is set, any letters in a class represent both their
+upper case and lower case versions, so for example, a caseless [aeiou] matches
+"A" as well as "a", and a caseless [^aeiou] does not match "A", whereas a
+caseful version would.
+
+The newline character is never treated in any special way in character classes,
+whatever the setting of the PCRE_DOTALL or PCRE_MULTILINE options is. A class
+such as [^a] will always match a newline.
+
+The minus (hyphen) character can be used to specify a range of characters in a
+character class. For example, [d-m] matches any letter between d and m,
+inclusive. If a minus character is required in a class, it must be escaped with
+a backslash or appear in a position where it cannot be interpreted as
+indicating a range, typically as the first or last character in the class.
+
+It is not possible to have the literal character "]" as the end character of a
+range. A pattern such as [W-]46] is interpreted as a class of two characters
+("W" and "-") followed by a literal string "46]", so it would match "W46]" or
+"-46]". However, if the "]" is escaped with a backslash it is interpreted as
+the end of range, so [W-\\]46] is interpreted as a single class containing a
+range followed by two separate characters. The octal or hexadecimal
+representation of "]" can also be used to end a range.
+
+Ranges operate in ASCII collating sequence. They can also be used for
+characters specified numerically, for example [\\000-\\037]. If a range that
+includes letters is used when caseless matching is set, it matches the letters
+in either case. For example, [W-c] is equivalent to [][\\^_`wxyzabc], matched
+caselessly, and if character tables for the "fr" locale are in use,
+[\\xc8-\\xcb] matches accented E characters in both cases.
+
+The character types \\d, \\D, \\s, \\S, \\w, and \\W may also appear in a
+character class, and add the characters that they match to the class. For
+example, [\\dABCDEF] matches any hexadecimal digit. A circumflex can
+conveniently be used with the upper case character types to specify a more
+restricted set of characters than the matching lower case type. For example,
+the class [^\\W_] matches any letter or digit, but not underscore.
+
+All non-alphameric characters other than \\, -, ^ (at the start) and the
+terminating ] are non-special in character classes, but it does no harm if they
+are escaped.
+
+
+.SH POSIX CHARACTER CLASSES
+Perl 5.6 (not yet released at the time of writing) is going to support the
+POSIX notation for character classes, which uses names enclosed by [: and :]
+within the enclosing square brackets. PCRE supports this notation. For example,
+
+  [01[:alpha:]%]
+
+matches "0", "1", any alphabetic character, or "%". The supported class names
+are
+
+  alnum    letters and digits
+  alpha    letters
+  ascii    character codes 0 - 127
+  cntrl    control characters
+  digit    decimal digits (same as \\d)
+  graph    printing characters, excluding space
+  lower    lower case letters
+  print    printing characters, including space
+  punct    printing characters, excluding letters and digits
+  space    white space (same as \\s)
+  upper    upper case letters
+  word     "word" characters (same as \\w)
+  xdigit   hexadecimal digits
+
+The names "ascii" and "word" are Perl extensions. Another Perl extension is
+negation, which is indicated by a ^ character after the colon. For example,
+
+  [12[:^digit:]]
+
+matches "1", "2", or any non-digit. PCRE (and Perl) also recogize the POSIX
+syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not
+supported, and an error is given if they are encountered.
+
+
+.SH VERTICAL BAR
+Vertical bar characters are used to separate alternative patterns. For example,
+the pattern
+
+  gilbert|sullivan
+
+matches either "gilbert" or "sullivan". Any number of alternatives may appear,
+and an empty alternative is permitted (matching the empty string).
+The matching process tries each alternative in turn, from left to right,
+and the first one that succeeds is used. If the alternatives are within a
+subpattern (defined below), "succeeds" means matching the rest of the main
+pattern as well as the alternative in the subpattern.
+
+
+.SH INTERNAL OPTION SETTING
+The settings of PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and PCRE_EXTENDED
+can be changed from within the pattern by a sequence of Perl option letters
+enclosed between "(?" and ")". The option letters are
+
+  i  for PCRE_CASELESS
+  m  for PCRE_MULTILINE
+  s  for PCRE_DOTALL
+  x  for PCRE_EXTENDED
+
+For example, (?im) sets caseless, multiline matching. It is also possible to
+unset these options by preceding the letter with a hyphen, and a combined
+setting and unsetting such as (?im-sx), which sets PCRE_CASELESS and
+PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED, is also
+permitted. If a letter appears both before and after the hyphen, the option is
+unset.
+
+The scope of these option changes depends on where in the pattern the setting
+occurs. For settings that are outside any subpattern (defined below), the
+effect is the same as if the options were set or unset at the start of
+matching. The following patterns all behave in exactly the same way:
+
+  (?i)abc
+  a(?i)bc
+  ab(?i)c
+  abc(?i)
+
+which in turn is the same as compiling the pattern abc with PCRE_CASELESS set.
+In other words, such "top level" settings apply to the whole pattern (unless
+there are other changes inside subpatterns). If there is more than one setting
+of the same option at top level, the rightmost setting is used.
+
+If an option change occurs inside a subpattern, the effect is different. This
+is a change of behaviour in Perl 5.005. An option change inside a subpattern
+affects only that part of the subpattern that follows it, so
+
+  (a(?i)b)c
+
+matches abc and aBc and no other strings (assuming PCRE_CASELESS is not used).
+By this means, options can be made to have different settings in different
+parts of the pattern. Any changes made in one alternative do carry on
+into subsequent branches within the same subpattern. For example,
+
+  (a(?i)b|c)
+
+matches "ab", "aB", "c", and "C", even though when matching "C" the first
+branch is abandoned before the option setting. This is because the effects of
+option settings happen at compile time. There would be some very weird
+behaviour otherwise.
+
+The PCRE-specific options PCRE_UNGREEDY and PCRE_EXTRA can be changed in the
+same way as the Perl-compatible options by using the characters U and X
+respectively. The (?X) flag setting is special in that it must always occur
+earlier in the pattern than any of the additional features it turns on, even
+when it is at top level. It is best put at the start.
+
+
+.SH SUBPATTERNS
+Subpatterns are delimited by parentheses (round brackets), which can be nested.
+Marking part of a pattern as a subpattern does two things:
+
+1. It localizes a set of alternatives. For example, the pattern
+
+  cat(aract|erpillar|)
+
+matches one of the words "cat", "cataract", or "caterpillar". Without the
+parentheses, it would match "cataract", "erpillar" or the empty string.
+
+2. It sets up the subpattern as a capturing subpattern (as defined above).
+When the whole pattern matches, that portion of the subject string that matched
+the subpattern is passed back to the caller via the \fIovector\fR argument of
+\fBpcre_exec()\fR. Opening parentheses are counted from left to right (starting
+from 1) to obtain the numbers of the capturing subpatterns.
+
+For example, if the string "the red king" is matched against the pattern
+
+  the ((red|white) (king|queen))
+
+the captured substrings are "red king", "red", and "king", and are numbered 1,
+2, and 3.
+
+The fact that plain parentheses fulfil two functions is not always helpful.
+There are often times when a grouping subpattern is required without a
+capturing requirement. If an opening parenthesis is followed by "?:", the
+subpattern does not do any capturing, and is not counted when computing the
+number of any subsequent capturing subpatterns. For example, if the string "the
+white queen" is matched against the pattern
+
+  the ((?:red|white) (king|queen))
+
+the captured substrings are "white queen" and "queen", and are numbered 1 and
+2. The maximum number of captured substrings is 99, and the maximum number of
+all subpatterns, both capturing and non-capturing, is 200.
+
+As a convenient shorthand, if any option settings are required at the start of
+a non-capturing subpattern, the option letters may appear between the "?" and
+the ":". Thus the two patterns
+
+  (?i:saturday|sunday)
+  (?:(?i)saturday|sunday)
+
+match exactly the same set of strings. Because alternative branches are tried
+from left to right, and options are not reset until the end of the subpattern
+is reached, an option setting in one branch does affect subsequent branches, so
+the above patterns match "SUNDAY" as well as "Saturday".
+
+
+.SH REPETITION
+Repetition is specified by quantifiers, which can follow any of the following
+items:
+
+  a single character, possibly escaped
+  the . metacharacter
+  a character class
+  a back reference (see next section)
+  a parenthesized subpattern (unless it is an assertion - see below)
+
+The general repetition quantifier specifies a minimum and maximum number of
+permitted matches, by giving the two numbers in curly brackets (braces),
+separated by a comma. The numbers must be less than 65536, and the first must
+be less than or equal to the second. For example:
+
+  z{2,4}
+
+matches "zz", "zzz", or "zzzz". A closing brace on its own is not a special
+character. If the second number is omitted, but the comma is present, there is
+no upper limit; if the second number and the comma are both omitted, the
+quantifier specifies an exact number of required matches. Thus
+
+  [aeiou]{3,}
+
+matches at least 3 successive vowels, but may match many more, while
+
+  \\d{8}
+
+matches exactly 8 digits. An opening curly bracket that appears in a position
+where a quantifier is not allowed, or one that does not match the syntax of a
+quantifier, is taken as a literal character. For example, {,6} is not a
+quantifier, but a literal string of four characters.
+
+The quantifier {0} is permitted, causing the expression to behave as if the
+previous item and the quantifier were not present.
+
+For convenience (and historical compatibility) the three most common
+quantifiers have single-character abbreviations:
+
+  *    is equivalent to {0,}
+  +    is equivalent to {1,}
+  ?    is equivalent to {0,1}
+
+It is possible to construct infinite loops by following a subpattern that can
+match no characters with a quantifier that has no upper limit, for example:
+
+  (a?)*
+
+Earlier versions of Perl and PCRE used to give an error at compile time for
+such patterns. However, because there are cases where this can be useful, such
+patterns are now accepted, but if any repetition of the subpattern does in fact
+match no characters, the loop is forcibly broken.
+
+By default, the quantifiers are "greedy", that is, they match as much as
+possible (up to the maximum number of permitted times), without causing the
+rest of the pattern to fail. The classic example of where this gives problems
+is in trying to match comments in C programs. These appear between the
+sequences /* and */ and within the sequence, individual * and / characters may
+appear. An attempt to match C comments by applying the pattern
+
+  /\\*.*\\*/
+
+to the string
+
+  /* first command */  not comment  /* second comment */
+
+fails, because it matches the entire string due to the greediness of the .*
+item.
+
+However, if a quantifier is followed by a question mark, then it ceases to be
+greedy, and instead matches the minimum number of times possible, so the
+pattern
+
+  /\\*.*?\\*/
+
+does the right thing with the C comments. The meaning of the various
+quantifiers is not otherwise changed, just the preferred number of matches.
+Do not confuse this use of question mark with its use as a quantifier in its
+own right. Because it has two uses, it can sometimes appear doubled, as in
+
+  \\d??\\d
+
+which matches one digit by preference, but can match two if that is the only
+way the rest of the pattern matches.
+
+If the PCRE_UNGREEDY option is set (an option which is not available in Perl)
+then the quantifiers are not greedy by default, but individual ones can be made
+greedy by following them with a question mark. In other words, it inverts the
+default behaviour.
+
+When a parenthesized subpattern is quantified with a minimum repeat count that
+is greater than 1 or with a limited maximum, more store is required for the
+compiled pattern, in proportion to the size of the minimum or maximum.
+
+If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equivalent
+to Perl's /s) is set, thus allowing the . to match newlines, then the pattern
+is implicitly anchored, because whatever follows will be tried against every
+character position in the subject string, so there is no point in retrying the
+overall match at any position after the first. PCRE treats such a pattern as
+though it were preceded by \\A. In cases where it is known that the subject
+string contains no newlines, it is worth setting PCRE_DOTALL when the pattern
+begins with .* in order to obtain this optimization, or alternatively using ^
+to indicate anchoring explicitly.
+
+When a capturing subpattern is repeated, the value captured is the substring
+that matched the final iteration. For example, after
+
+  (tweedle[dume]{3}\\s*)+
+
+has matched "tweedledum tweedledee" the value of the captured substring is
+"tweedledee". However, if there are nested capturing subpatterns, the
+corresponding captured values may have been set in previous iterations. For
+example, after
+
+  /(a|(b))+/
+
+matches "aba" the value of the second captured substring is "b".
+
+
+.SH BACK REFERENCES
+Outside a character class, a backslash followed by a digit greater than 0 (and
+possibly further digits) is a back reference to a capturing subpattern earlier
+(i.e. to its left) in the pattern, provided there have been that many previous
+capturing left parentheses.
+
+However, if the decimal number following the backslash is less than 10, it is
+always taken as a back reference, and causes an error only if there are not
+that many capturing left parentheses in the entire pattern. In other words, the
+parentheses that are referenced need not be to the left of the reference for
+numbers less than 10. See the section entitled "Backslash" above for further
+details of the handling of digits following a backslash.
+
+A back reference matches whatever actually matched the capturing subpattern in
+the current subject string, rather than anything matching the subpattern
+itself. So the pattern
+
+  (sens|respons)e and \\1ibility
+
+matches "sense and sensibility" and "response and responsibility", but not
+"sense and responsibility". If caseful matching is in force at the time of the
+back reference, then the case of letters is relevant. For example,
+
+  ((?i)rah)\\s+\\1
+
+matches "rah rah" and "RAH RAH", but not "RAH rah", even though the original
+capturing subpattern is matched caselessly.
+
+There may be more than one back reference to the same subpattern. If a
+subpattern has not actually been used in a particular match, then any back
+references to it always fail. For example, the pattern
+
+  (a|(bc))\\2
+
+always fails if it starts to match "a" rather than "bc". Because there may be
+up to 99 back references, all digits following the backslash are taken
+as part of a potential back reference number. If the pattern continues with a
+digit character, then some delimiter must be used to terminate the back
+reference. If the PCRE_EXTENDED option is set, this can be whitespace.
+Otherwise an empty comment can be used.
+
+A back reference that occurs inside the parentheses to which it refers fails
+when the subpattern is first used, so, for example, (a\\1) never matches.
+However, such references can be useful inside repeated subpatterns. For
+example, the pattern
+
+  (a|b\\1)+
+
+matches any number of "a"s and also "aba", "ababaa" etc. At each iteration of
+the subpattern, the back reference matches the character string corresponding
+to the previous iteration. In order for this to work, the pattern must be such
+that the first iteration does not need to match the back reference. This can be
+done using alternation, as in the example above, or by a quantifier with a
+minimum of zero.
+
+
+.SH ASSERTIONS
+An assertion is a test on the characters following or preceding the current
+matching point that does not actually consume any characters. The simple
+assertions coded as \\b, \\B, \\A, \\Z, \\z, ^ and $ are described above. More
+complicated assertions are coded as subpatterns. There are two kinds: those
+that look ahead of the current position in the subject string, and those 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. Lookahead assertions start
+with (?= for positive assertions and (?! for negative assertions. For example,
+
+  \\w+(?=;)
+
+matches a word followed by a semicolon, but does not include the semicolon in
+the match, and
+
+  foo(?!bar)
+
+matches any occurrence of "foo" that is not followed by "bar". Note that the
+apparently similar pattern
+
+  (?!foo)bar
+
+does not find an occurrence of "bar" that is preceded by something other than
+"foo"; it finds any occurrence of "bar" whatsoever, because the assertion
+(?!foo) is always true when the next three characters are "bar". A
+lookbehind assertion is needed to achieve this effect.
+
+Lookbehind assertions start with (?<= for positive assertions and (?<! for
+negative assertions. For example,
+
+  (?<!foo)bar
+
+does find an occurrence of "bar" that is not preceded by "foo". The contents of
+a lookbehind assertion are restricted such that all the strings it matches must
+have a fixed length. However, if there are several alternatives, they do not
+all have to have the same fixed length. Thus
+
+  (?<=bullock|donkey)
+
+is permitted, but
+
+  (?<!dogs?|cats?)
+
+causes an error at compile time. Branches that match different length strings
+are permitted only at the top level of a lookbehind assertion. This is an
+extension compared with Perl 5.005, which requires all branches to match the
+same length of string. An assertion such as
+
+  (?<=ab(c|de))
+
+is not permitted, because its single top-level branch can match two different
+lengths, but it is acceptable if rewritten to use two top-level branches:
+
+  (?<=abc|abde)
+
+The implementation of lookbehind assertions is, for each alternative, to
+temporarily move the current position back by the fixed width and then try to
+match. If there are insufficient characters before the current position, the
+match is deemed to fail. Lookbehinds in conjunction with once-only subpatterns
+can be particularly useful for matching at the ends of strings; an example is
+given at the end of the section on once-only subpatterns.
+
+Several assertions (of any sort) may occur in succession. For example,
+
+  (?<=\\d{3})(?<!999)foo
+
+matches "foo" preceded by three digits that are not "999". Notice that each of
+the assertions is applied independently at the same point in the subject
+string. First there is a check that the previous three characters are all
+digits, then there is a check that the same three characters are not "999".
+This pattern does \fInot\fR match "foo" preceded by six characters, the first
+of which are digits and the last three of which are not "999". For example, it
+doesn't match "123abcfoo". A pattern to do that is
+
+  (?<=\\d{3}...)(?<!999)foo
+
+This time the first assertion looks at the preceding six characters, checking
+that the first three are digits, and then the second assertion checks that the
+preceding three characters are not "999".
+
+Assertions can be nested in any combination. For example,
+
+  (?<=(?<!foo)bar)baz
+
+matches an occurrence of "baz" that is preceded by "bar" which in turn is not
+preceded by "foo", while
+
+  (?<=\\d{3}(?!999)...)foo
+
+is another pattern which matches "foo" preceded by three digits and any three
+characters that are not "999".
+
+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.
+
+Assertions count towards the maximum of 200 parenthesized subpatterns.
+
+
+.SH ONCE-ONLY SUBPATTERNS
+With both maximizing and minimizing repetition, failure of what follows
+normally causes the repeated item to be re-evaluated to see if a different
+number of repeats allows the rest of the pattern to match. Sometimes it is
+useful to prevent this, either to change the nature of the match, or to cause
+it fail earlier than it otherwise might, when the author of the pattern knows
+there is no point in carrying on.
+
+Consider, for example, the pattern \\d+foo when applied to the subject line
+
+  123456bar
+
+After matching all 6 digits and then failing to match "foo", the normal
+action of the matcher is to try again with only 5 digits matching the \\d+
+item, and then with 4, and so on, before ultimately failing. Once-only
+subpatterns provide the means for specifying that once a portion of the pattern
+has matched, it is not to be re-evaluated in this way, so the matcher would
+give up immediately on failing to match "foo" the first time. The notation is
+another kind of special parenthesis, starting with (?> as in this example:
+
+  (?>\\d+)bar
+
+This kind of parenthesis "locks up" the  part of the pattern it contains once
+it has matched, and a failure further into the pattern is prevented from
+backtracking into it. Backtracking past it to previous items, however, works as
+normal.
+
+An alternative description is that a subpattern of this type matches the string
+of characters that an identical standalone pattern would match, if anchored at
+the current point in the subject string.
+
+Once-only subpatterns are not capturing subpatterns. Simple cases such as the
+above example can be thought of as a maximizing repeat that must swallow
+everything it can. So, while both \\d+ and \\d+? are prepared to adjust the
+number of digits they match in order to make the rest of the pattern match,
+(?>\\d+) can only match an entire sequence of digits.
+
+This construction can of course contain arbitrarily complicated subpatterns,
+and it can be nested.
+
+Once-only subpatterns can be used in conjunction with lookbehind assertions to
+specify efficient matching at the end of the subject string. Consider a simple
+pattern such as
+
+  abcd$
+
+when applied to a long string which does not match. Because matching proceeds
+from left to right, PCRE will look for each "a" in the subject and then see if
+what follows matches the rest of the pattern. If the pattern is specified as
+
+  ^.*abcd$
+
+then the initial .* matches the entire string at first, but when this fails
+(because there is no following "a"), it backtracks to match all but the last
+character, then all but the last two characters, and so on. Once again the
+search for "a" covers the entire string, from right to left, so we are no
+better off. However, if the pattern is written as
+
+  ^(?>.*)(?<=abcd)
+
+then there can be no backtracking for the .* item; it can match only the entire
+string. The subsequent lookbehind assertion does a single test on the last four
+characters. If it fails, the match fails immediately. For long strings, this
+approach makes a significant difference to the processing time.
+
+When a pattern contains an unlimited repeat inside a subpattern that can itself
+be repeated an unlimited number of times, the use of a once-only subpattern is
+the only way to avoid some failing matches taking a very long time indeed.
+The pattern
+
+  (\\D+|<\\d+>)*[!?]
+
+matches an unlimited number of substrings that either consist of non-digits, or
+digits enclosed in <>, followed by either ! or ?. When it matches, it runs
+quickly. However, if it is applied to
+
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+
+it takes a long time before reporting failure. This is because the string can
+be divided between the two repeats in a large number of ways, and all have to
+be tried. (The example used [!?] rather than a single character at the end,
+because both PCRE and Perl have an optimization that allows for fast failure
+when a single character is used. They remember the last single character that
+is required for a match, and fail early if it is not present in the string.)
+If the pattern is changed to
+
+  ((?>\\D+)|<\\d+>)*[!?]
+
+sequences of non-digits cannot be broken, and failure happens quickly.
+
+
+.SH CONDITIONAL SUBPATTERNS
+It is possible to cause the matching process to obey a subpattern
+conditionally or to choose between two alternative subpatterns, depending on
+the result of an assertion, or whether a previous capturing subpattern matched
+or not. The two possible forms of conditional subpattern are
+
+  (?(condition)yes-pattern)
+  (?(condition)yes-pattern|no-pattern)
+
+If the condition is satisfied, the yes-pattern is used; otherwise the
+no-pattern (if present) is used. If there are more than two alternatives in the
+subpattern, a compile-time error occurs.
+
+There are two kinds of condition. If the text between the parentheses consists
+of a sequence of digits, then the condition is satisfied if the capturing
+subpattern of that number has previously matched. Consider the following
+pattern, which contains non-significant white space to make it more readable
+(assume the PCRE_EXTENDED option) and to divide it into three parts for ease
+of discussion:
+
+  ( \\( )?    [^()]+    (?(1) \\) )
+
+The first part matches an optional opening parenthesis, and if that
+character is present, sets it as the first captured substring. The second part
+matches one or more characters that are not parentheses. The third part is a
+conditional subpattern that tests whether the first set of parentheses matched
+or not. If they did, that is, if subject started with an opening parenthesis,
+the condition is true, and so the yes-pattern is executed and a closing
+parenthesis is required. Otherwise, since no-pattern is not present, the
+subpattern matches nothing. In other words, this pattern matches a sequence of
+non-parentheses, optionally enclosed in parentheses.
+
+If the condition is not a sequence of digits, it must be an assertion. This may
+be a positive or negative lookahead or lookbehind assertion. Consider this
+pattern, again containing non-significant white space, and with the two
+alternatives on the second line:
+
+  (?(?=[^a-z]*[a-z])
+  \\d{2}-[a-z]{3}-\\d{2}  |  \\d{2}-\\d{2}-\\d{2} )
+
+The condition is a positive lookahead assertion that matches an optional
+sequence of non-letters followed by a letter. In other words, it tests for the
+presence of at least one letter in the subject. If a letter is found, the
+subject is matched against the first alternative; otherwise it is matched
+against the second. This pattern matches strings in one of the two forms
+dd-aaa-dd or dd-dd-dd, where aaa are letters and dd are digits.
+
+
+.SH COMMENTS
+The sequence (?# marks the start of a comment which continues up to the next
+closing parenthesis. Nested parentheses are not permitted. The characters
+that make up a comment play no part in the pattern matching at all.
+
+If the PCRE_EXTENDED option is set, an unescaped # character outside a
+character class introduces a comment that continues up to the next newline
+character in the pattern.
+
+
+.SH RECURSIVE PATTERNS
+Consider the problem of matching a string in parentheses, allowing for
+unlimited nested parentheses. Without the use of recursion, the best that can
+be done is to use a pattern that matches up to some fixed depth of nesting. It
+is not possible to handle an arbitrary nesting depth. Perl 5.6 has provided an
+experimental facility that allows regular expressions to recurse (amongst other
+things). It does this by interpolating Perl code in the expression at run time,
+and the code can refer to the expression itself. A Perl pattern to solve the
+parentheses problem can be created like this:
+
+  $re = qr{\\( (?: (?>[^()]+) | (?p{$re}) )* \\)}x;
+
+The (?p{...}) item interpolates Perl code at run time, and in this case refers
+recursively to the pattern in which it appears. Obviously, PCRE cannot support
+the interpolation of Perl code. Instead, the special item (?R) is provided for
+the specific case of recursion. This PCRE pattern solves the parentheses
+problem (assume the PCRE_EXTENDED option is set so that white space is
+ignored):
+
+  \\( ( (?>[^()]+) | (?R) )* \\)
+
+First it matches an opening parenthesis. Then it matches any number of
+substrings which can either be a sequence of non-parentheses, or a recursive
+match of the pattern itself (i.e. a correctly parenthesized substring). Finally
+there is a closing parenthesis.
+
+This particular example pattern contains nested unlimited repeats, and so the
+use of a once-only subpattern for matching strings of non-parentheses is
+important when applying the pattern to strings that do not match. For example,
+when it is applied to
+
+  (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
+
+it yields "no match" quickly. However, if a once-only subpattern is not used,
+the match runs for a very long time indeed because there are so many different
+ways the + and * repeats can carve up the subject, and all have to be tested
+before failure can be reported.
+
+The values set for any capturing subpatterns are those from the outermost level
+of the recursion at which the subpattern value is set. If the pattern above is
+matched against
+
+  (ab(cd)ef)
+
+the value for the capturing parentheses is "ef", which is the last value taken
+on at the top level. If additional parentheses are added, giving
+
+  \\( ( ( (?>[^()]+) | (?R) )* ) \\)
+     ^                        ^
+     ^                        ^
+then the string they capture is "ab(cd)ef", the contents of the top level
+parentheses. If there are more than 15 capturing parentheses in a pattern, PCRE
+has to obtain extra memory to store data during a recursion, which it does by
+using \fBpcre_malloc\fR, freeing it via \fBpcre_free\fR afterwards. If no
+memory can be obtained, it saves data for the first 15 capturing parentheses
+only, as there is no way to give an out-of-memory error from within a
+recursion.
+
+
+.SH PERFORMANCE
+Certain items that may appear in patterns are more efficient than others. It is
+more efficient to use a character class like [aeiou] than a set of alternatives
+such as (a|e|i|o|u). In general, the simplest construction that provides the
+required behaviour is usually the most efficient. Jeffrey Friedl's book
+contains a lot of discussion about optimizing regular expressions for efficient
+performance.
+
+When a pattern begins with .* and the PCRE_DOTALL option is set, the pattern is
+implicitly anchored by PCRE, since it can match only at the start of a subject
+string. However, if PCRE_DOTALL is not set, PCRE cannot make this optimization,
+because the . metacharacter does not then match a newline, and if the subject
+string contains newlines, the pattern may match from the character immediately
+following one of them instead of from the very start. For example, the pattern
+
+  (.*) second
+
+matches the subject "first\\nand second" (where \\n stands for a newline
+character) with the first captured substring being "and". In order to do this,
+PCRE has to retry the match starting after every newline in the subject.
+
+If you are using such a pattern with subject strings that do not contain
+newlines, the best performance is obtained by setting PCRE_DOTALL, or starting
+the pattern with ^.* to indicate explicit anchoring. That saves PCRE from
+having to scan along the subject looking for a newline to restart at.
+
+Beware of patterns that contain nested indefinite repeats. These can take a
+long time to run when applied to a string that does not match. Consider the
+pattern fragment
+
+  (a+)*
+
+This can match "aaaa" in 33 different ways, and this number increases very
+rapidly as the string gets longer. (The * repeat can match 0, 1, 2, 3, or 4
+times, and for each of those cases other than 0, the + repeats can match
+different numbers of times.) When the remainder of the pattern is such that the
+entire match is going to fail, PCRE has in principle to try every possible
+variation, and this can take an extremely long time.
+
+An optimization catches some of the more simple cases such as
+
+  (a+)*b
+
+where a literal character follows. Before embarking on the standard matching
+procedure, PCRE checks that there is a "b" later in the subject string, and if
+there is not, it fails the match immediately. However, when there is no
+following literal this optimization cannot be used. You can see the difference
+by comparing the behaviour of
+
+  (a+)*\\d
+
+with the pattern above. The former gives a failure almost instantly when
+applied to a whole line of "a" characters, whereas the latter takes an
+appreciable time with strings longer than about 20 characters.
+
+.SH AUTHOR
+Philip Hazel <ph10@cam.ac.uk>
+.br
+University Computing Service,
+.br
+New Museums Site,
+.br
+Cambridge CB2 3QG, England.
+.br
+Phone: +44 1223 334714
+
+Last updated: 27 January 2000
+.br
+Copyright (c) 1997-2000 University of Cambridge.
diff --git a/ext/pcre/pcrelib/doc/pcre.html b/ext/pcre/pcrelib/doc/pcre.html
new file mode 100644 (file)
index 0000000..2ce2890
--- /dev/null
@@ -0,0 +1,2259 @@
+<HTML>
+<HEAD>
+<TITLE>pcre specification</TITLE>
+</HEAD>
+<body bgcolor="#FFFFFF" text="#00005A">
+<H1>pcre specification</H1>
+This HTML document has been generated automatically from the original man page.
+If there is any nonsense in it, please consult the man page in case the
+conversion went wrong.
+<UL>
+<LI><A NAME="TOC1" HREF="#SEC1">NAME</A>
+<LI><A NAME="TOC2" HREF="#SEC2">SYNOPSIS</A>
+<LI><A NAME="TOC3" HREF="#SEC3">DESCRIPTION</A>
+<LI><A NAME="TOC4" HREF="#SEC4">MULTI-THREADING</A>
+<LI><A NAME="TOC5" HREF="#SEC5">COMPILING A PATTERN</A>
+<LI><A NAME="TOC6" HREF="#SEC6">STUDYING A PATTERN</A>
+<LI><A NAME="TOC7" HREF="#SEC7">LOCALE SUPPORT</A>
+<LI><A NAME="TOC8" HREF="#SEC8">INFORMATION ABOUT A PATTERN</A>
+<LI><A NAME="TOC9" HREF="#SEC9">MATCHING A PATTERN</A>
+<LI><A NAME="TOC10" HREF="#SEC10">EXTRACTING CAPTURED SUBSTRINGS</A>
+<LI><A NAME="TOC11" HREF="#SEC11">LIMITATIONS</A>
+<LI><A NAME="TOC12" HREF="#SEC12">DIFFERENCES FROM PERL</A>
+<LI><A NAME="TOC13" HREF="#SEC13">REGULAR EXPRESSION DETAILS</A>
+<LI><A NAME="TOC14" HREF="#SEC14">BACKSLASH</A>
+<LI><A NAME="TOC15" HREF="#SEC15">CIRCUMFLEX AND DOLLAR</A>
+<LI><A NAME="TOC16" HREF="#SEC16">FULL STOP (PERIOD, DOT)</A>
+<LI><A NAME="TOC17" HREF="#SEC17">SQUARE BRACKETS</A>
+<LI><A NAME="TOC18" HREF="#SEC18">POSIX CHARACTER CLASSES</A>
+<LI><A NAME="TOC19" HREF="#SEC19">VERTICAL BAR</A>
+<LI><A NAME="TOC20" HREF="#SEC20">INTERNAL OPTION SETTING</A>
+<LI><A NAME="TOC21" HREF="#SEC21">SUBPATTERNS</A>
+<LI><A NAME="TOC22" HREF="#SEC22">REPETITION</A>
+<LI><A NAME="TOC23" HREF="#SEC23">BACK REFERENCES</A>
+<LI><A NAME="TOC24" HREF="#SEC24">ASSERTIONS</A>
+<LI><A NAME="TOC25" HREF="#SEC25">ONCE-ONLY SUBPATTERNS</A>
+<LI><A NAME="TOC26" HREF="#SEC26">CONDITIONAL SUBPATTERNS</A>
+<LI><A NAME="TOC27" HREF="#SEC27">COMMENTS</A>
+<LI><A NAME="TOC28" HREF="#SEC28">RECURSIVE PATTERNS</A>
+<LI><A NAME="TOC29" HREF="#SEC29">PERFORMANCE</A>
+<LI><A NAME="TOC30" HREF="#SEC30">AUTHOR</A>
+</UL>
+<LI><A NAME="SEC1" HREF="#TOC1">NAME</A>
+<P>
+pcre - Perl-compatible regular expressions.
+</P>
+<LI><A NAME="SEC2" HREF="#TOC1">SYNOPSIS</A>
+<P>
+<B>#include &#60;pcre.h&#62;</B>
+</P>
+<P>
+<B>pcre *pcre_compile(const char *<I>pattern</I>, int <I>options</I>,</B>
+<B>const char **<I>errptr</I>, int *<I>erroffset</I>,</B>
+<B>const unsigned char *<I>tableptr</I>);</B>
+</P>
+<P>
+<B>pcre_extra *pcre_study(const pcre *<I>code</I>, int <I>options</I>,</B>
+<B>const char **<I>errptr</I>);</B>
+</P>
+<P>
+<B>int pcre_exec(const pcre *<I>code</I>, const pcre_extra *<I>extra</I>,</B>
+<B>const char *<I>subject</I>, int <I>length</I>, int <I>startoffset</I>,</B>
+<B>int <I>options</I>, int *<I>ovector</I>, int <I>ovecsize</I>);</B>
+</P>
+<P>
+<B>int pcre_copy_substring(const char *<I>subject</I>, int *<I>ovector</I>,</B>
+<B>int <I>stringcount</I>, int <I>stringnumber</I>, char *<I>buffer</I>,</B>
+<B>int <I>buffersize</I>);</B>
+</P>
+<P>
+<B>int pcre_get_substring(const char *<I>subject</I>, int *<I>ovector</I>,</B>
+<B>int <I>stringcount</I>, int <I>stringnumber</I>,</B>
+<B>const char **<I>stringptr</I>);</B>
+</P>
+<P>
+<B>int pcre_get_substring_list(const char *<I>subject</I>,</B>
+<B>int *<I>ovector</I>, int <I>stringcount</I>, const char ***<I>listptr</I>);</B>
+</P>
+<P>
+<B>const unsigned char *pcre_maketables(void);</B>
+</P>
+<P>
+<B>int pcre_fullinfo(const pcre *<I>code</I>, const pcre_extra *<I>extra</I>,</B>
+<B>int <I>what</I>, void *<I>where</I>);</B>
+</P>
+<P>
+<B>int pcre_info(const pcre *<I>code</I>, int *<I>optptr</I>, int</B>
+<B>*<I>firstcharptr</I>);</B>
+</P>
+<P>
+<B>char *pcre_version(void);</B>
+</P>
+<P>
+<B>void *(*pcre_malloc)(size_t);</B>
+</P>
+<P>
+<B>void (*pcre_free)(void *);</B>
+</P>
+<LI><A NAME="SEC3" HREF="#TOC1">DESCRIPTION</A>
+<P>
+The PCRE library is a set of functions that implement regular expression
+pattern matching using the same syntax and semantics as Perl 5, with just a few
+differences (see below). The current implementation corresponds to Perl 5.005,
+with some additional features from the Perl development release.
+</P>
+<P>
+PCRE has its own native API, which is described in this document. There is also
+a set of wrapper functions that correspond to the POSIX regular expression API.
+These are described in the <B>pcreposix</B> documentation.
+</P>
+<P>
+The native API function prototypes are defined in the header file <B>pcre.h</B>,
+and on Unix systems the library itself is called <B>libpcre.a</B>, so can be
+accessed by adding <B>-lpcre</B> to the command for linking an application which
+calls it. The header file defines the macros PCRE_MAJOR and PCRE_MINOR to
+contain the major and minor release numbers for the library. Applications can
+use these to include support for different releases.
+</P>
+<P>
+The functions <B>pcre_compile()</B>, <B>pcre_study()</B>, and <B>pcre_exec()</B>
+are used for compiling and matching regular expressions, while
+<B>pcre_copy_substring()</B>, <B>pcre_get_substring()</B>, and
+<B>pcre_get_substring_list()</B> are convenience functions for extracting
+captured substrings from a matched subject string. The function
+<B>pcre_maketables()</B> is used (optionally) to build a set of character tables
+in the current locale for passing to <B>pcre_compile()</B>.
+</P>
+<P>
+The function <B>pcre_fullinfo()</B> is used to find out information about a
+compiled pattern; <B>pcre_info()</B> is an obsolete version which returns only
+some of the available information, but is retained for backwards compatibility.
+The function <B>pcre_version()</B> returns a pointer to a string containing the
+version of PCRE and its date of release.
+</P>
+<P>
+The global variables <B>pcre_malloc</B> and <B>pcre_free</B> initially contain
+the entry points of the standard <B>malloc()</B> and <B>free()</B> functions
+respectively. PCRE calls the memory management functions via these variables,
+so a calling program can replace them if it wishes to intercept the calls. This
+should be done before calling any PCRE functions.
+</P>
+<LI><A NAME="SEC4" HREF="#TOC1">MULTI-THREADING</A>
+<P>
+The PCRE functions can be used in multi-threading applications, with the
+proviso that the memory management functions pointed to by <B>pcre_malloc</B>
+and <B>pcre_free</B> are shared by all threads.
+</P>
+<P>
+The compiled form of a regular expression is not altered during matching, so
+the same compiled pattern can safely be used by several threads at once.
+</P>
+<LI><A NAME="SEC5" HREF="#TOC1">COMPILING A PATTERN</A>
+<P>
+The function <B>pcre_compile()</B> is called to compile a pattern into an
+internal form. The pattern is a C string terminated by a binary zero, and
+is passed in the argument <I>pattern</I>. A pointer to a single block of memory
+that is obtained via <B>pcre_malloc</B> is returned. This contains the
+compiled code and related data. The <B>pcre</B> type is defined for this for
+convenience, but in fact <B>pcre</B> is just a typedef for <B>void</B>, since the
+contents of the block are not externally defined. It is up to the caller to
+free the memory when it is no longer required.
+</P>
+<P>
+The size of a compiled pattern is roughly proportional to the length of the
+pattern string, except that each character class (other than those containing
+just a single character, negated or not) requires 33 bytes, and repeat
+quantifiers with a minimum greater than one or a bounded maximum cause the
+relevant portions of the compiled pattern to be replicated.
+</P>
+<P>
+The <I>options</I> argument contains independent bits that affect the
+compilation. It should be zero if no options are required. Some of the options,
+in particular, those that are compatible with Perl, can also be set and unset
+from within the pattern (see the detailed description of regular expressions
+below). For these options, the contents of the <I>options</I> argument specifies
+their initial settings at the start of compilation and execution. The
+PCRE_ANCHORED option can be set at the time of matching as well as at compile
+time.
+</P>
+<P>
+If <I>errptr</I> is NULL, <B>pcre_compile()</B> returns NULL immediately.
+Otherwise, if compilation of a pattern fails, <B>pcre_compile()</B> returns
+NULL, and sets the variable pointed to by <I>errptr</I> to point to a textual
+error message. The offset from the start of the pattern to the character where
+the error was discovered is placed in the variable pointed to by
+<I>erroffset</I>, which must not be NULL. If it is, an immediate error is given.
+</P>
+<P>
+If the final argument, <I>tableptr</I>, is NULL, PCRE uses a default set of
+character tables which are built when it is compiled, using the default C
+locale. Otherwise, <I>tableptr</I> must be the result of a call to
+<B>pcre_maketables()</B>. See the section on locale support below.
+</P>
+<P>
+The following option bits are defined in the header file:
+</P>
+<P>
+<PRE>
+  PCRE_ANCHORED
+</PRE>
+</P>
+<P>
+If this bit is set, the pattern is forced to be "anchored", that is, it is
+constrained to match only at the start of the string which is being searched
+(the "subject string"). This effect can also be achieved by appropriate
+constructs in the pattern itself, which is the only way to do it in Perl.
+</P>
+<P>
+<PRE>
+  PCRE_CASELESS
+</PRE>
+</P>
+<P>
+If this bit is set, letters in the pattern match both upper and lower case
+letters. It is equivalent to Perl's /i option.
+</P>
+<P>
+<PRE>
+  PCRE_DOLLAR_ENDONLY
+</PRE>
+</P>
+<P>
+If this bit is set, a dollar metacharacter in the pattern matches only at the
+end of the subject string. Without this option, a dollar also matches
+immediately before the final character if it is a newline (but not before any
+other newlines). The PCRE_DOLLAR_ENDONLY option is ignored if PCRE_MULTILINE is
+set. There is no equivalent to this option in Perl.
+</P>
+<P>
+<PRE>
+  PCRE_DOTALL
+</PRE>
+</P>
+<P>
+If this bit is set, a dot metacharater in the pattern matches all characters,
+including newlines. Without it, newlines are excluded. This option is
+equivalent to Perl's /s option. A negative class such as [^a] always matches a
+newline character, independent of the setting of this option.
+</P>
+<P>
+<PRE>
+  PCRE_EXTENDED
+</PRE>
+</P>
+<P>
+If this bit is set, whitespace data characters in the pattern are totally
+ignored except when escaped or inside a character class, and characters between
+an unescaped # outside a character class and the next newline character,
+inclusive, are also ignored. This is equivalent to Perl's /x option, and makes
+it possible to include comments inside complicated patterns. Note, however,
+that this applies only to data characters. Whitespace characters may never
+appear within special character sequences in a pattern, for example within the
+sequence (?( which introduces a conditional subpattern.
+</P>
+<P>
+<PRE>
+  PCRE_EXTRA
+</PRE>
+</P>
+<P>
+This option was invented in order to turn on additional functionality of PCRE
+that is incompatible with Perl, but it is currently of very little use. When
+set, any backslash in a pattern that is followed by a letter that has no
+special meaning causes an error, thus reserving these combinations for future
+expansion. By default, as in Perl, a backslash followed by a letter with no
+special meaning is treated as a literal. There are at present no other features
+controlled by this option. It can also be set by a (?X) option setting within a
+pattern.
+</P>
+<P>
+<PRE>
+  PCRE_MULTILINE
+</PRE>
+</P>
+<P>
+By default, PCRE treats the subject string as consisting of a single "line" of
+characters (even if it actually contains several newlines). The "start of line"
+metacharacter (^) matches only at the start of the string, while the "end of
+line" metacharacter ($) matches only at the end of the string, or before a
+terminating newline (unless PCRE_DOLLAR_ENDONLY is set). This is the same as
+Perl.
+</P>
+<P>
+When PCRE_MULTILINE it is set, the "start of line" and "end of line" constructs
+match immediately following or immediately before any newline in the subject
+string, respectively, as well as at the very start and end. This is equivalent
+to Perl's /m option. If there are no "\n" characters in a subject string, or
+no occurrences of ^ or $ in a pattern, setting PCRE_MULTILINE has no
+effect.
+</P>
+<P>
+<PRE>
+  PCRE_UNGREEDY
+</PRE>
+</P>
+<P>
+This option inverts the "greediness" of the quantifiers so that they are not
+greedy by default, but become greedy if followed by "?". It is not compatible
+with Perl. It can also be set by a (?U) option setting within the pattern.
+</P>
+<LI><A NAME="SEC6" HREF="#TOC1">STUDYING A PATTERN</A>
+<P>
+When a pattern is going to be used several times, it is worth spending more
+time analyzing it in order to speed up the time taken for matching. The
+function <B>pcre_study()</B> takes a pointer to a compiled pattern as its first
+argument, and returns a pointer to a <B>pcre_extra</B> block (another <B>void</B>
+typedef) containing additional information about the pattern; this can be
+passed to <B>pcre_exec()</B>. If no additional information is available, NULL
+is returned.
+</P>
+<P>
+The second argument contains option bits. At present, no options are defined
+for <B>pcre_study()</B>, and this argument should always be zero.
+</P>
+<P>
+The third argument for <B>pcre_study()</B> is a pointer to an error message. If
+studying succeeds (even if no data is returned), the variable it points to is
+set to NULL. Otherwise it points to a textual error message.
+</P>
+<P>
+At present, studying a pattern is useful only for non-anchored patterns that do
+not have a single fixed starting character. A bitmap of possible starting
+characters is created.
+</P>
+<LI><A NAME="SEC7" HREF="#TOC1">LOCALE SUPPORT</A>
+<P>
+PCRE handles caseless matching, and determines whether characters are letters,
+digits, or whatever, by reference to a set of tables. The library contains a
+default set of tables which is created in the default C locale when PCRE is
+compiled. This is used when the final argument of <B>pcre_compile()</B> is NULL,
+and is sufficient for many applications.
+</P>
+<P>
+An alternative set of tables can, however, be supplied. Such tables are built
+by calling the <B>pcre_maketables()</B> function, which has no arguments, in the
+relevant locale. The result can then be passed to <B>pcre_compile()</B> as often
+as necessary. For example, to build and use tables that are appropriate for the
+French locale (where accented characters with codes greater than 128 are
+treated as letters), the following code could be used:
+</P>
+<P>
+<PRE>
+  setlocale(LC_CTYPE, "fr");
+  tables = pcre_maketables();
+  re = pcre_compile(..., tables);
+</PRE>
+</P>
+<P>
+The tables are built in memory that is obtained via <B>pcre_malloc</B>. The
+pointer that is passed to <B>pcre_compile</B> is saved with the compiled
+pattern, and the same tables are used via this pointer by <B>pcre_study()</B>
+and <B>pcre_exec()</B>. Thus for any single pattern, compilation, studying and
+matching all happen in the same locale, but different patterns can be compiled
+in different locales. It is the caller's responsibility to ensure that the
+memory containing the tables remains available for as long as it is needed.
+</P>
+<LI><A NAME="SEC8" HREF="#TOC1">INFORMATION ABOUT A PATTERN</A>
+<P>
+The <B>pcre_fullinfo()</B> function returns information about a compiled
+pattern. It replaces the obsolete <B>pcre_info()</B> function, which is
+nevertheless retained for backwards compability (and is documented below).
+</P>
+<P>
+The first argument for <B>pcre_fullinfo()</B> is a pointer to the compiled
+pattern. The second argument is the result of <B>pcre_study()</B>, or NULL if
+the pattern was not studied. The third argument specifies which piece of
+information is required, while the fourth argument is a pointer to a variable
+to receive the data. The yield of the function is zero for success, or one of
+the following negative numbers:
+</P>
+<P>
+<PRE>
+  PCRE_ERROR_NULL       the argument <I>code</I> was NULL
+                        the argument <I>where</I> was NULL
+  PCRE_ERROR_BADMAGIC   the "magic number" was not found
+  PCRE_ERROR_BADOPTION  the value of <I>what</I> was invalid
+</PRE>
+</P>
+<P>
+The possible values for the third argument are defined in <B>pcre.h</B>, and are
+as follows:
+</P>
+<P>
+<PRE>
+  PCRE_INFO_OPTIONS
+</PRE>
+</P>
+<P>
+Return a copy of the options with which the pattern was compiled. The fourth
+argument should point to au <B>unsigned long int</B> variable. These option bits
+are those specified in the call to <B>pcre_compile()</B>, modified by any
+top-level option settings within the pattern itself, and with the PCRE_ANCHORED
+bit forcibly set if the form of the pattern implies that it can match only at
+the start of a subject string.
+</P>
+<P>
+<PRE>
+  PCRE_INFO_SIZE
+</PRE>
+</P>
+<P>
+Return the size of the compiled pattern, that is, the value that was passed as
+the argument to <B>pcre_malloc()</B> when PCRE was getting memory in which to
+place the compiled data. The fourth argument should point to a <B>size_t</B>
+variable.
+</P>
+<P>
+<PRE>
+  PCRE_INFO_CAPTURECOUNT
+</PRE>
+</P>
+<P>
+Return the number of capturing subpatterns in the pattern. The fourth argument
+should point to an \fbint\fR variable.
+</P>
+<P>
+<PRE>
+  PCRE_INFO_BACKREFMAX
+</PRE>
+</P>
+<P>
+Return the number of the highest back reference in the pattern. The fourth
+argument should point to an <B>int</B> variable. Zero is returned if there are
+no back references.
+</P>
+<P>
+<PRE>
+  PCRE_INFO_FIRSTCHAR
+</PRE>
+</P>
+<P>
+Return information about the first character of any matched string, for a
+non-anchored pattern. If there is a fixed first character, e.g. from a pattern
+such as (cat|cow|coyote), then it is returned in the integer pointed to by
+<I>where</I>. Otherwise, if either
+</P>
+<P>
+(a) the pattern was compiled with the PCRE_MULTILINE option, and every branch
+starts with "^", or
+</P>
+<P>
+(b) every branch of the pattern starts with ".*" and PCRE_DOTALL is not set
+(if it were set, the pattern would be anchored),
+</P>
+<P>
+then -1 is returned, indicating that the pattern matches only at the
+start of a subject string or after any "\n" within the string. Otherwise -2 is
+returned. For anchored patterns, -2 is returned.
+</P>
+<P>
+<PRE>
+  PCRE_INFO_FIRSTTABLE
+</PRE>
+</P>
+<P>
+If the pattern was studied, and this resulted in the construction of a 256-bit
+table indicating a fixed set of characters for the first character in any
+matching string, a pointer to the table is returned. Otherwise NULL is
+returned. The fourth argument should point to an <B>unsigned char *</B>
+variable.
+</P>
+<P>
+<PRE>
+  PCRE_INFO_LASTLITERAL
+</PRE>
+</P>
+<P>
+For a non-anchored pattern, return the value of the rightmost literal character
+which must exist in any matched string, other than at its start. The fourth
+argument should point to an <B>int</B> variable. If there is no such character,
+or if the pattern is anchored, -1 is returned. For example, for the pattern
+/a\d+z\d+/ the returned value is 'z'.
+</P>
+<P>
+The <B>pcre_info()</B> function is now obsolete because its interface is too
+restrictive to return all the available data about a compiled pattern. New
+programs should use <B>pcre_fullinfo()</B> instead. The yield of
+<B>pcre_info()</B> is the number of capturing subpatterns, or one of the
+following negative numbers:
+</P>
+<P>
+<PRE>
+  PCRE_ERROR_NULL       the argument <I>code</I> was NULL
+  PCRE_ERROR_BADMAGIC   the "magic number" was not found
+</PRE>
+</P>
+<P>
+If the <I>optptr</I> argument is not NULL, a copy of the options with which the
+pattern was compiled is placed in the integer it points to (see
+PCRE_INFO_OPTIONS above).
+</P>
+<P>
+If the pattern is not anchored and the <I>firstcharptr</I> argument is not NULL,
+it is used to pass back information about the first character of any matched
+string (see PCRE_INFO_FIRSTCHAR above).
+</P>
+<LI><A NAME="SEC9" HREF="#TOC1">MATCHING A PATTERN</A>
+<P>
+The function <B>pcre_exec()</B> is called to match a subject string against a
+pre-compiled pattern, which is passed in the <I>code</I> argument. If the
+pattern has been studied, the result of the study should be passed in the
+<I>extra</I> argument. Otherwise this must be NULL.
+</P>
+<P>
+The PCRE_ANCHORED option can be passed in the <I>options</I> argument, whose
+unused bits must be zero. However, if a pattern was compiled with
+PCRE_ANCHORED, or turned out to be anchored by virtue of its contents, it
+cannot be made unachored at matching time.
+</P>
+<P>
+There are also three further options that can be set only at matching time:
+</P>
+<P>
+<PRE>
+  PCRE_NOTBOL
+</PRE>
+</P>
+<P>
+The first character of the string is not the beginning of a line, so the
+circumflex metacharacter should not match before it. Setting this without
+PCRE_MULTILINE (at compile time) causes circumflex never to match.
+</P>
+<P>
+<PRE>
+  PCRE_NOTEOL
+</PRE>
+</P>
+<P>
+The end of the string is not the end of a line, so the dollar metacharacter
+should not match it nor (except in multiline mode) a newline immediately before
+it. Setting this without PCRE_MULTILINE (at compile time) causes dollar never
+to match.
+</P>
+<P>
+<PRE>
+  PCRE_NOTEMPTY
+</PRE>
+</P>
+<P>
+An empty string is not considered to be a valid match if this option is set. If
+there are alternatives in the pattern, they are tried. If all the alternatives
+match the empty string, the entire match fails. For example, if the pattern
+</P>
+<P>
+<PRE>
+  a?b?
+</PRE>
+</P>
+<P>
+is applied to a string not beginning with "a" or "b", it matches the empty
+string at the start of the subject. With PCRE_NOTEMPTY set, this match is not
+valid, so PCRE searches further into the string for occurrences of "a" or "b".
+</P>
+<P>
+Perl has no direct equivalent of PCRE_NOTEMPTY, but it does make a special case
+of a pattern match of the empty string within its <B>split()</B> function, and
+when using the /g modifier. It is possible to emulate Perl's behaviour after
+matching a null string by first trying the match again at the same offset with
+PCRE_NOTEMPTY set, and then if that fails by advancing the starting offset (see
+below) and trying an ordinary match again.
+</P>
+<P>
+The subject string is passed as a pointer in <I>subject</I>, a length in
+<I>length</I>, and a starting offset in <I>startoffset</I>. Unlike the pattern
+string, it may contain binary zero characters. When the starting offset is
+zero, the search for a match starts at the beginning of the subject, and this
+is by far the most common case.
+</P>
+<P>
+A non-zero starting offset is useful when searching for another match in the
+same subject by calling <B>pcre_exec()</B> again after a previous success.
+Setting <I>startoffset</I> differs from just passing over a shortened string and
+setting PCRE_NOTBOL in the case of a pattern that begins with any kind of
+lookbehind. For example, consider the pattern
+</P>
+<P>
+<PRE>
+  \Biss\B
+</PRE>
+</P>
+<P>
+which finds occurrences of "iss" in the middle of words. (\B matches only if
+the current position in the subject is not a word boundary.) When applied to
+the string "Mississipi" the first call to <B>pcre_exec()</B> finds the first
+occurrence. If <B>pcre_exec()</B> is called again with just the remainder of the
+subject, namely "issipi", it does not match, because \B is always false at the
+start of the subject, which is deemed to be a word boundary. However, if
+<B>pcre_exec()</B> is passed the entire string again, but with <I>startoffset</I>
+set to 4, it finds the second occurrence of "iss" because it is able to look
+behind the starting point to discover that it is preceded by a letter.
+</P>
+<P>
+If a non-zero starting offset is passed when the pattern is anchored, one
+attempt to match at the given offset is tried. This can only succeed if the
+pattern does not require the match to be at the start of the subject.
+</P>
+<P>
+In general, a pattern matches a certain portion of the subject, and in
+addition, further substrings from the subject may be picked out by parts of the
+pattern. Following the usage in Jeffrey Friedl's book, this is called
+"capturing" in what follows, and the phrase "capturing subpattern" is used for
+a fragment of a pattern that picks out a substring. PCRE supports several other
+kinds of parenthesized subpattern that do not cause substrings to be captured.
+</P>
+<P>
+Captured substrings are returned to the caller via a vector of integer offsets
+whose address is passed in <I>ovector</I>. The number of elements in the vector
+is passed in <I>ovecsize</I>. The first two-thirds of the vector is used to pass
+back captured substrings, each substring using a pair of integers. The
+remaining third of the vector is used as workspace by <B>pcre_exec()</B> while
+matching capturing subpatterns, and is not available for passing back
+information. The length passed in <I>ovecsize</I> should always be a multiple of
+three. If it is not, it is rounded down.
+</P>
+<P>
+When a match has been successful, information about captured substrings is
+returned in pairs of integers, starting at the beginning of <I>ovector</I>, and
+continuing up to two-thirds of its length at the most. The first element of a
+pair is set to the offset of the first character in a substring, and the second
+is set to the offset of the first character after the end of a substring. The
+first pair, <I>ovector[0]</I> and <I>ovector[1]</I>, identify the portion of the
+subject string matched by the entire pattern. The next pair is used for the
+first capturing subpattern, and so on. The value returned by <B>pcre_exec()</B>
+is the number of pairs that have been set. If there are no capturing
+subpatterns, the return value from a successful match is 1, indicating that
+just the first pair of offsets has been set.
+</P>
+<P>
+Some convenience functions are provided for extracting the captured substrings
+as separate strings. These are described in the following section.
+</P>
+<P>
+It is possible for an capturing subpattern number <I>n+1</I> to match some
+part of the subject when subpattern <I>n</I> has not been used at all. For
+example, if the string "abc" is matched against the pattern (a|(z))(bc)
+subpatterns 1 and 3 are matched, but 2 is not. When this happens, both offset
+values corresponding to the unused subpattern are set to -1.
+</P>
+<P>
+If a capturing subpattern is matched repeatedly, it is the last portion of the
+string that it matched that gets returned.
+</P>
+<P>
+If the vector is too small to hold all the captured substrings, it is used as
+far as possible (up to two-thirds of its length), and the function returns a
+value of zero. In particular, if the substring offsets are not of interest,
+<B>pcre_exec()</B> may be called with <I>ovector</I> passed as NULL and
+<I>ovecsize</I> as zero. However, if the pattern contains back references and
+the <I>ovector</I> isn't big enough to remember the related substrings, PCRE has
+to get additional memory for use during matching. Thus it is usually advisable
+to supply an <I>ovector</I>.
+</P>
+<P>
+Note that <B>pcre_info()</B> can be used to find out how many capturing
+subpatterns there are in a compiled pattern. The smallest size for
+<I>ovector</I> that will allow for <I>n</I> captured substrings in addition to
+the offsets of the substring matched by the whole pattern is (<I>n</I>+1)*3.
+</P>
+<P>
+If <B>pcre_exec()</B> fails, it returns a negative number. The following are
+defined in the header file:
+</P>
+<P>
+<PRE>
+  PCRE_ERROR_NOMATCH        (-1)
+</PRE>
+</P>
+<P>
+The subject string did not match the pattern.
+</P>
+<P>
+<PRE>
+  PCRE_ERROR_NULL           (-2)
+</PRE>
+</P>
+<P>
+Either <I>code</I> or <I>subject</I> was passed as NULL, or <I>ovector</I> was
+NULL and <I>ovecsize</I> was not zero.
+</P>
+<P>
+<PRE>
+  PCRE_ERROR_BADOPTION      (-3)
+</PRE>
+</P>
+<P>
+An unrecognized bit was set in the <I>options</I> argument.
+</P>
+<P>
+<PRE>
+  PCRE_ERROR_BADMAGIC       (-4)
+</PRE>
+</P>
+<P>
+PCRE stores a 4-byte "magic number" at the start of the compiled code, to catch
+the case when it is passed a junk pointer. This is the error it gives when the
+magic number isn't present.
+</P>
+<P>
+<PRE>
+  PCRE_ERROR_UNKNOWN_NODE   (-5)
+</PRE>
+</P>
+<P>
+While running the pattern match, an unknown item was encountered in the
+compiled pattern. This error could be caused by a bug in PCRE or by overwriting
+of the compiled pattern.
+</P>
+<P>
+<PRE>
+  PCRE_ERROR_NOMEMORY       (-6)
+</PRE>
+</P>
+<P>
+If a pattern contains back references, but the <I>ovector</I> that is passed to
+<B>pcre_exec()</B> is not big enough to remember the referenced substrings, PCRE
+gets a block of memory at the start of matching to use for this purpose. If the
+call via <B>pcre_malloc()</B> fails, this error is given. The memory is freed at
+the end of matching.
+</P>
+<LI><A NAME="SEC10" HREF="#TOC1">EXTRACTING CAPTURED SUBSTRINGS</A>
+<P>
+Captured substrings can be accessed directly by using the offsets returned by
+<B>pcre_exec()</B> in <I>ovector</I>. For convenience, the functions
+<B>pcre_copy_substring()</B>, <B>pcre_get_substring()</B>, and
+<B>pcre_get_substring_list()</B> are provided for extracting captured substrings
+as new, separate, zero-terminated strings. A substring that contains a binary
+zero is correctly extracted and has a further zero added on the end, but the
+result does not, of course, function as a C string.
+</P>
+<P>
+The first three arguments are the same for all three functions: <I>subject</I>
+is the subject string which has just been successfully matched, <I>ovector</I>
+is a pointer to the vector of integer offsets that was passed to
+<B>pcre_exec()</B>, and <I>stringcount</I> is the number of substrings that
+were captured by the match, including the substring that matched the entire
+regular expression. This is the value returned by <B>pcre_exec</B> if it
+is greater than zero. If <B>pcre_exec()</B> returned zero, indicating that it
+ran out of space in <I>ovector</I>, then the value passed as
+<I>stringcount</I> should be the size of the vector divided by three.
+</P>
+<P>
+The functions <B>pcre_copy_substring()</B> and <B>pcre_get_substring()</B>
+extract a single substring, whose number is given as <I>stringnumber</I>. A
+value of zero extracts the substring that matched the entire pattern, while
+higher values extract the captured substrings. For <B>pcre_copy_substring()</B>,
+the string is placed in <I>buffer</I>, whose length is given by
+<I>buffersize</I>, while for <B>pcre_get_substring()</B> a new block of store is
+obtained via <B>pcre_malloc</B>, and its address is returned via
+<I>stringptr</I>. The yield of the function is the length of the string, not
+including the terminating zero, or one of
+</P>
+<P>
+<PRE>
+  PCRE_ERROR_NOMEMORY       (-6)
+</PRE>
+</P>
+<P>
+The buffer was too small for <B>pcre_copy_substring()</B>, or the attempt to get
+memory failed for <B>pcre_get_substring()</B>.
+</P>
+<P>
+<PRE>
+  PCRE_ERROR_NOSUBSTRING    (-7)
+</PRE>
+</P>
+<P>
+There is no substring whose number is <I>stringnumber</I>.
+</P>
+<P>
+The <B>pcre_get_substring_list()</B> function extracts all available substrings
+and builds a list of pointers to them. All this is done in a single block of
+memory which is obtained via <B>pcre_malloc</B>. The address of the memory block
+is returned via <I>listptr</I>, which is also the start of the list of string
+pointers. The end of the list is marked by a NULL pointer. The yield of the
+function is zero if all went well, or
+</P>
+<P>
+<PRE>
+  PCRE_ERROR_NOMEMORY       (-6)
+</PRE>
+</P>
+<P>
+if the attempt to get the memory block failed.
+</P>
+<P>
+When any of these functions encounter a substring that is unset, which can
+happen when capturing subpattern number <I>n+1</I> matches some part of the
+subject, but subpattern <I>n</I> has not been used at all, they return an empty
+string. This can be distinguished from a genuine zero-length substring by
+inspecting the appropriate offset in <I>ovector</I>, which is negative for unset
+substrings.
+</P>
+<LI><A NAME="SEC11" HREF="#TOC1">LIMITATIONS</A>
+<P>
+There are some size limitations in PCRE but it is hoped that they will never in
+practice be relevant.
+The maximum length of a compiled pattern is 65539 (sic) bytes.
+All values in repeating quantifiers must be less than 65536.
+The maximum number of capturing subpatterns is 99.
+The maximum number of all parenthesized subpatterns, including capturing
+subpatterns, assertions, and other types of subpattern, is 200.
+</P>
+<P>
+The maximum length of a subject string is the largest positive number that an
+integer variable can hold. However, PCRE uses recursion to handle subpatterns
+and indefinite repetition. This means that the available stack space may limit
+the size of a subject string that can be processed by certain patterns.
+</P>
+<LI><A NAME="SEC12" HREF="#TOC1">DIFFERENCES FROM PERL</A>
+<P>
+The differences described here are with respect to Perl 5.005.
+</P>
+<P>
+1. By default, a whitespace character is any character that the C library
+function <B>isspace()</B> recognizes, though it is possible to compile PCRE with
+alternative character type tables. Normally <B>isspace()</B> matches space,
+formfeed, newline, carriage return, horizontal tab, and vertical tab. Perl 5
+no longer includes vertical tab in its set of whitespace characters. The \v
+escape that was in the Perl documentation for a long time was never in fact
+recognized. However, the character itself was treated as whitespace at least
+up to 5.002. In 5.004 and 5.005 it does not match \s.
+</P>
+<P>
+2. PCRE does not allow repeat quantifiers on lookahead 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.
+</P>
+<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
+numerical variables from any such patterns that are matched before the
+assertion fails to match something (thereby succeeding), but only if the
+negative lookahead assertion contains just one branch.
+</P>
+<P>
+4. Though binary zero characters are supported in the subject string, they are
+not allowed in a pattern string because it is passed as a normal C string,
+terminated by zero. The escape sequence "\0" can be used in the pattern to
+represent a binary zero.
+</P>
+<P>
+5. The following Perl escape sequences are not supported: \l, \u, \L, \U,
+\E, \Q. In fact these are implemented by Perl's general string-handling and
+are not part of its pattern matching engine.
+</P>
+<P>
+6. The Perl \G assertion is not supported as it is not relevant to single
+pattern matches.
+</P>
+<P>
+7. Fairly obviously, PCRE does not support the (?{code}) and (?p{code})
+constructions. However, there is some experimental support for recursive
+patterns using the non-Perl item (?R).
+</P>
+<P>
+8. There are at the time of writing some oddities in Perl 5.005_02 concerned
+with the settings of captured strings when part of a pattern is repeated. For
+example, matching "aba" against the pattern /^(a(b)?)+$/ sets $2 to the value
+"b", but matching "aabbaa" against /^(aa(bb)?)+$/ leaves $2 unset. However, if
+the pattern is changed to /^(aa(b(b))?)+$/ then $2 (and $3) get set.
+</P>
+<P>
+In Perl 5.004 $2 is set in both cases, and that is also true of PCRE. If in the
+future Perl changes to a consistent state that is different, PCRE may change to
+follow.
+</P>
+<P>
+9. Another as yet unresolved discrepancy is that in Perl 5.005_02 the pattern
+/^(a)?(?(1)a|b)+$/ matches the string "a", whereas in PCRE it does not.
+However, in both Perl and PCRE /^(a)?a/ matched against "a" leaves $1 unset.
+</P>
+<P>
+10. PCRE provides some extensions to the Perl regular expression facilities:
+</P>
+<P>
+(a) Although lookbehind assertions must match fixed length strings, each
+alternative branch of a lookbehind assertion can match a different length of
+string. Perl 5.005 requires them all to have the same length.
+</P>
+<P>
+(b) If PCRE_DOLLAR_ENDONLY is set and PCRE_MULTILINE is not set, the $ meta-
+character matches only at the very end of the string.
+</P>
+<P>
+(c) If PCRE_EXTRA is set, a backslash followed by a letter with no special
+meaning is faulted.
+</P>
+<P>
+(d) If PCRE_UNGREEDY is set, the greediness of the repetition quantifiers is
+inverted, that is, by default they are not greedy, but if followed by a
+question mark they are.
+</P>
+<P>
+(e) PCRE_ANCHORED can be used to force a pattern to be tried only at the start
+of the subject.
+</P>
+<P>
+(f) The PCRE_NOTBOL, PCRE_NOTEOL, and PCRE_NOTEMPTY options for
+<B>pcre_exec()</B> have no Perl equivalents.
+</P>
+<P>
+(g) The (?R) construct allows for recursive pattern matching (Perl 5.6 can do
+this using the (?p{code}) construct, which PCRE cannot of course support.)
+</P>
+<LI><A NAME="SEC13" HREF="#TOC1">REGULAR EXPRESSION DETAILS</A>
+<P>
+The syntax and semantics of the regular expressions supported by PCRE are
+described below. Regular expressions are also described in the Perl
+documentation and in a number of other books, some of which have copious
+examples. Jeffrey Friedl's "Mastering Regular Expressions", published by
+O'Reilly (ISBN 1-56592-257), covers them in great detail. The description
+here is intended as reference documentation.
+</P>
+<P>
+A regular expression is a pattern that is matched against a subject string from
+left to right. Most characters stand for themselves in a pattern, and match the
+corresponding characters in the subject. As a trivial example, the pattern
+</P>
+<P>
+<PRE>
+  The quick brown fox
+</PRE>
+</P>
+<P>
+matches a portion of a subject string that is identical to itself. The power of
+regular expressions comes from the ability to include alternatives and
+repetitions in the pattern. These are encoded in the pattern by the use of
+<I>meta-characters</I>, which do not stand for themselves but instead are
+interpreted in some special way.
+</P>
+<P>
+There are two different sets of meta-characters: those that are recognized
+anywhere in the pattern except within square brackets, and those that are
+recognized in square brackets. Outside square brackets, the meta-characters are
+as follows:
+</P>
+<P>
+<PRE>
+  \      general escape character with several uses
+  ^      assert start of subject (or line, in multiline mode)
+  $      assert end of subject (or line, in multiline mode)
+  .      match any character except newline (by default)
+  [      start character class definition
+  |      start of alternative branch
+  (      start subpattern
+  )      end subpattern
+  ?      extends the meaning of (
+         also 0 or 1 quantifier
+         also quantifier minimizer
+  *      0 or more quantifier
+  +      1 or more quantifier
+  {      start min/max quantifier
+</PRE>
+</P>
+<P>
+Part of a pattern that is in square brackets is called a "character class". In
+a character class the only meta-characters are:
+</P>
+<P>
+<PRE>
+  \      general escape character
+  ^      negate the class, but only if the first character
+  -      indicates character range
+  ]      terminates the character class
+</PRE>
+</P>
+<P>
+The following sections describe the use of each of the meta-characters.
+</P>
+<LI><A NAME="SEC14" HREF="#TOC1">BACKSLASH</A>
+<P>
+The backslash character has several uses. Firstly, if it is followed by a
+non-alphameric character, it takes away any special meaning that character may
+have. This use of backslash as an escape character applies both inside and
+outside character classes.
+</P>
+<P>
+For example, if you want to match a "*" character, you write "\*" in the
+pattern. This applies whether or not the following character would otherwise be
+interpreted as a meta-character, so it is always safe to precede a
+non-alphameric with "\" to specify that it stands for itself. In particular,
+if you want to match a backslash, you write "\\".
+</P>
+<P>
+If a pattern is compiled with the PCRE_EXTENDED option, whitespace in the
+pattern (other than in a character class) and characters between a "#" outside
+a character class and the next newline character are ignored. An escaping
+backslash can be used to include a whitespace or "#" character as part of the
+pattern.
+</P>
+<P>
+A second use of backslash provides a way of encoding non-printing characters
+in patterns in a visible manner. There is no restriction on the appearance of
+non-printing characters, apart from the binary zero that terminates a pattern,
+but when a pattern is being prepared by text editing, it is usually easier to
+use one of the following escape sequences than the binary character it
+represents:
+</P>
+<P>
+<PRE>
+  \a     alarm, that is, the BEL character (hex 07)
+  \cx    "control-x", where x is any character
+  \e     escape (hex 1B)
+  \f     formfeed (hex 0C)
+  \n     newline (hex 0A)
+  \r     carriage return (hex 0D)
+  \t     tab (hex 09)
+  \xhh   character with hex code hh
+  \ddd   character with octal code ddd, or backreference
+</PRE>
+</P>
+<P>
+The precise effect of "\cx" is as follows: if "x" is a lower case letter, it
+is converted to upper case. Then bit 6 of the character (hex 40) is inverted.
+Thus "\cz" becomes hex 1A, but "\c{" becomes hex 3B, while "\c;" becomes hex
+7B.
+</P>
+<P>
+After "\x", up to two hexadecimal digits are read (letters can be in upper or
+lower case).
+</P>
+<P>
+After "\0" up to two further octal digits are read. In both cases, if there
+are fewer than two digits, just those that are present are used. Thus the
+sequence "\0\x\07" specifies two binary zeros followed by a BEL character.
+Make sure you supply two digits after the initial zero if the character that
+follows is itself an octal digit.
+</P>
+<P>
+The handling of a backslash followed by a digit other than 0 is complicated.
+Outside a character class, PCRE reads it and any following digits as a decimal
+number. If the number is less than 10, or if there have been at least that many
+previous capturing left parentheses in the expression, the entire sequence is
+taken as a <I>back reference</I>. A description of how this works is given
+later, following the discussion of parenthesized subpatterns.
+</P>
+<P>
+Inside a character class, or if the decimal number is greater than 9 and there
+have not been that many capturing subpatterns, PCRE re-reads up to three octal
+digits following the backslash, and generates a single byte from the least
+significant 8 bits of the value. Any subsequent digits stand for themselves.
+For example:
+</P>
+<P>
+<PRE>
+  \040   is another way of writing a space
+  \40    is the same, provided there are fewer than 40
+            previous capturing subpatterns
+  \7     is always a back reference
+  \11    might be a back reference, or another way of
+            writing a tab
+  \011   is always a tab
+  \0113  is a tab followed by the character "3"
+  \113   is the character with octal code 113 (since there
+            can be no more than 99 back references)
+  \377   is a byte consisting entirely of 1 bits
+  \81    is either a back reference, or a binary zero
+            followed by the two characters "8" and "1"
+</PRE>
+</P>
+<P>
+Note that octal values of 100 or greater must not be introduced by a leading
+zero, because no more than three octal digits are ever read.
+</P>
+<P>
+All the sequences that define a single byte value can be used both inside and
+outside character classes. In addition, inside a character class, the sequence
+"\b" is interpreted as the backspace character (hex 08). Outside a character
+class it has a different meaning (see below).
+</P>
+<P>
+The third use of backslash is for specifying generic character types:
+</P>
+<P>
+<PRE>
+  \d     any decimal digit
+  \D     any character that is not a decimal digit
+  \s     any whitespace character
+  \S     any character that is not a whitespace character
+  \w     any "word" character
+  \W     any "non-word" character
+</PRE>
+</P>
+<P>
+Each pair of escape sequences partitions the complete set of characters into
+two disjoint sets. Any given character matches one, and only one, of each pair.
+</P>
+<P>
+A "word" character is any letter or digit or the underscore character, that is,
+any character which can be part of a Perl "word". The definition of letters and
+digits is controlled by PCRE's character tables, and may vary if locale-
+specific matching is taking place (see "Locale support" above). For example, in
+the "fr" (French) locale, some character codes greater than 128 are used for
+accented letters, and these are matched by \w.
+</P>
+<P>
+These character type sequences can appear both inside and outside character
+classes. They each match one character of the appropriate type. If the current
+matching point is at the end of the subject string, all of them fail, since
+there is no character to match.
+</P>
+<P>
+The fourth use of backslash is for certain simple assertions. An assertion
+specifies a condition that has to be met at a particular point in a match,
+without consuming any characters from the subject string. The use of
+subpatterns for more complicated assertions is described below. The backslashed
+assertions are
+</P>
+<P>
+<PRE>
+  \b     word boundary
+  \B     not a word boundary
+  \A     start of subject (independent of multiline mode)
+  \Z     end of subject or newline at end (independent of multiline mode)
+  \z     end of subject (independent of multiline mode)
+</PRE>
+</P>
+<P>
+These assertions may not appear in character classes (but note that "\b" has a
+different meaning, namely the backspace character, inside a character class).
+</P>
+<P>
+A word boundary is a position in the subject string where the current character
+and the previous character do not both match \w or \W (i.e. one matches
+\w and the other matches \W), or the start or end of the string if the
+first or last character matches \w, respectively.
+</P>
+<P>
+The \A, \Z, and \z assertions differ from the traditional circumflex and
+dollar (described below) in that they only ever match at the very start and end
+of the subject string, whatever options are set. They are not affected by the
+PCRE_NOTBOL or PCRE_NOTEOL options. If the <I>startoffset</I> argument of
+<B>pcre_exec()</B> is non-zero, \A can never match. The difference between \Z
+and \z is that \Z matches before a newline that is the last character of the
+string as well as at the end of the string, whereas \z matches only at the
+end.
+</P>
+<LI><A NAME="SEC15" HREF="#TOC1">CIRCUMFLEX AND DOLLAR</A>
+<P>
+Outside a character class, in the default matching mode, the circumflex
+character is an assertion which is true only if the current matching point is
+at the start of the subject string. If the <I>startoffset</I> argument of
+<B>pcre_exec()</B> is non-zero, circumflex can never match. Inside a character
+class, circumflex has an entirely different meaning (see below).
+</P>
+<P>
+Circumflex need not be the first character of the pattern if a number of
+alternatives are involved, but it should be the first thing in each alternative
+in which it appears if the pattern is ever to match that branch. If all
+possible alternatives start with a circumflex, that is, if the pattern is
+constrained to match only at the start of the subject, it is said to be an
+"anchored" pattern. (There are also other constructs that can cause a pattern
+to be anchored.)
+</P>
+<P>
+A dollar character is an assertion which is true only if the current matching
+point is at the end of the subject string, or immediately before a newline
+character that is the last character in the string (by default). Dollar need
+not be the last character of the pattern if a number of alternatives are
+involved, but it should be the last item in any branch in which it appears.
+Dollar has no special meaning in a character class.
+</P>
+<P>
+The meaning of dollar can be changed so that it matches only at the very end of
+the string, by setting the PCRE_DOLLAR_ENDONLY option at compile or matching
+time. This does not affect the \Z assertion.
+</P>
+<P>
+The meanings of the circumflex and dollar characters are changed if the
+PCRE_MULTILINE option is set. When this is the case, they match immediately
+after and immediately before an internal "\n" character, respectively, in
+addition to matching at the start and end of the subject string. For example,
+the pattern /^abc$/ matches the subject string "def\nabc" in multiline mode,
+but not otherwise. Consequently, patterns that are anchored in single line mode
+because all branches start with "^" are not anchored in multiline mode, and a
+match for circumflex is possible when the <I>startoffset</I> argument of
+<B>pcre_exec()</B> is non-zero. The PCRE_DOLLAR_ENDONLY option is ignored if
+PCRE_MULTILINE is set.
+</P>
+<P>
+Note that the sequences \A, \Z, and \z can be used to match the start and
+end of the subject in both modes, and if all branches of a pattern start with
+\A is it always anchored, whether PCRE_MULTILINE is set or not.
+</P>
+<LI><A NAME="SEC16" HREF="#TOC1">FULL STOP (PERIOD, DOT)</A>
+<P>
+Outside a character class, a dot in the pattern matches any one character in
+the subject, including a non-printing character, but not (by default) newline.
+If the PCRE_DOTALL option is set, then dots match newlines as well. The
+handling of dot is entirely independent of the handling of circumflex and
+dollar, the only relationship being that they both involve newline characters.
+Dot has no special meaning in a character class.
+</P>
+<LI><A NAME="SEC17" HREF="#TOC1">SQUARE BRACKETS</A>
+<P>
+An opening square bracket introduces a character class, terminated by a closing
+square bracket. A closing square bracket on its own is not special. If a
+closing square bracket is required as a member of the class, it should be the
+first data character in the class (after an initial circumflex, if present) or
+escaped with a backslash.
+</P>
+<P>
+A character class matches a single character in the subject; the character must
+be in the set of characters defined by the class, unless the first character in
+the class is a circumflex, in which case the subject character must not be in
+the set defined by the class. If a circumflex is actually required as a member
+of the class, ensure it is not the first character, or escape it with a
+backslash.
+</P>
+<P>
+For example, the character class [aeiou] matches any lower case vowel, while
+[^aeiou] matches any character that is not a lower case vowel. Note that a
+circumflex is just a convenient notation for specifying the characters which
+are in the class by enumerating those that are not. It is not an assertion: it
+still consumes a character from the subject string, and fails if the current
+pointer is at the end of the string.
+</P>
+<P>
+When caseless matching is set, any letters in a class represent both their
+upper case and lower case versions, so for example, a caseless [aeiou] matches
+"A" as well as "a", and a caseless [^aeiou] does not match "A", whereas a
+caseful version would.
+</P>
+<P>
+The newline character is never treated in any special way in character classes,
+whatever the setting of the PCRE_DOTALL or PCRE_MULTILINE options is. A class
+such as [^a] will always match a newline.
+</P>
+<P>
+The minus (hyphen) character can be used to specify a range of characters in a
+character class. For example, [d-m] matches any letter between d and m,
+inclusive. If a minus character is required in a class, it must be escaped with
+a backslash or appear in a position where it cannot be interpreted as
+indicating a range, typically as the first or last character in the class.
+</P>
+<P>
+It is not possible to have the literal character "]" as the end character of a
+range. A pattern such as [W-]46] is interpreted as a class of two characters
+("W" and "-") followed by a literal string "46]", so it would match "W46]" or
+"-46]". However, if the "]" is escaped with a backslash it is interpreted as
+the end of range, so [W-\]46] is interpreted as a single class containing a
+range followed by two separate characters. The octal or hexadecimal
+representation of "]" can also be used to end a range.
+</P>
+<P>
+Ranges operate in ASCII collating sequence. They can also be used for
+characters specified numerically, for example [\000-\037]. If a range that
+includes letters is used when caseless matching is set, it matches the letters
+in either case. For example, [W-c] is equivalent to [][\^_`wxyzabc], matched
+caselessly, and if character tables for the "fr" locale are in use,
+[\xc8-\xcb] matches accented E characters in both cases.
+</P>
+<P>
+The character types \d, \D, \s, \S, \w, and \W may also appear in a
+character class, and add the characters that they match to the class. For
+example, [\dABCDEF] matches any hexadecimal digit. A circumflex can
+conveniently be used with the upper case character types to specify a more
+restricted set of characters than the matching lower case type. For example,
+the class [^\W_] matches any letter or digit, but not underscore.
+</P>
+<P>
+All non-alphameric characters other than \, -, ^ (at the start) and the
+terminating ] are non-special in character classes, but it does no harm if they
+are escaped.
+</P>
+<LI><A NAME="SEC18" HREF="#TOC1">POSIX CHARACTER CLASSES</A>
+<P>
+Perl 5.6 (not yet released at the time of writing) is going to support the
+POSIX notation for character classes, which uses names enclosed by [: and :]
+within the enclosing square brackets. PCRE supports this notation. For example,
+</P>
+<P>
+<PRE>
+  [01[:alpha:]%]
+</PRE>
+</P>
+<P>
+matches "0", "1", any alphabetic character, or "%". The supported class names
+are
+</P>
+<P>
+<PRE>
+  alnum    letters and digits
+  alpha    letters
+  ascii    character codes 0 - 127
+  cntrl    control characters
+  digit    decimal digits (same as \d)
+  graph    printing characters, excluding space
+  lower    lower case letters
+  print    printing characters, including space
+  punct    printing characters, excluding letters and digits
+  space    white space (same as \s)
+  upper    upper case letters
+  word     "word" characters (same as \w)
+  xdigit   hexadecimal digits
+</PRE>
+</P>
+<P>
+The names "ascii" and "word" are Perl extensions. Another Perl extension is
+negation, which is indicated by a ^ character after the colon. For example,
+</P>
+<P>
+<PRE>
+  [12[:^digit:]]
+</PRE>
+</P>
+<P>
+matches "1", "2", or any non-digit. PCRE (and Perl) also recogize the POSIX
+syntax [.ch.] and [=ch=] where "ch" is a "collating element", but these are not
+supported, and an error is given if they are encountered.
+</P>
+<LI><A NAME="SEC19" HREF="#TOC1">VERTICAL BAR</A>
+<P>
+Vertical bar characters are used to separate alternative patterns. For example,
+the pattern
+</P>
+<P>
+<PRE>
+  gilbert|sullivan
+</PRE>
+</P>
+<P>
+matches either "gilbert" or "sullivan". Any number of alternatives may appear,
+and an empty alternative is permitted (matching the empty string).
+The matching process tries each alternative in turn, from left to right,
+and the first one that succeeds is used. If the alternatives are within a
+subpattern (defined below), "succeeds" means matching the rest of the main
+pattern as well as the alternative in the subpattern.
+</P>
+<LI><A NAME="SEC20" HREF="#TOC1">INTERNAL OPTION SETTING</A>
+<P>
+The settings of PCRE_CASELESS, PCRE_MULTILINE, PCRE_DOTALL, and PCRE_EXTENDED
+can be changed from within the pattern by a sequence of Perl option letters
+enclosed between "(?" and ")". The option letters are
+</P>
+<P>
+<PRE>
+  i  for PCRE_CASELESS
+  m  for PCRE_MULTILINE
+  s  for PCRE_DOTALL
+  x  for PCRE_EXTENDED
+</PRE>
+</P>
+<P>
+For example, (?im) sets caseless, multiline matching. It is also possible to
+unset these options by preceding the letter with a hyphen, and a combined
+setting and unsetting such as (?im-sx), which sets PCRE_CASELESS and
+PCRE_MULTILINE while unsetting PCRE_DOTALL and PCRE_EXTENDED, is also
+permitted. If a letter appears both before and after the hyphen, the option is
+unset.
+</P>
+<P>
+The scope of these option changes depends on where in the pattern the setting
+occurs. For settings that are outside any subpattern (defined below), the
+effect is the same as if the options were set or unset at the start of
+matching. The following patterns all behave in exactly the same way:
+</P>
+<P>
+<PRE>
+  (?i)abc
+  a(?i)bc
+  ab(?i)c
+  abc(?i)
+</PRE>
+</P>
+<P>
+which in turn is the same as compiling the pattern abc with PCRE_CASELESS set.
+In other words, such "top level" settings apply to the whole pattern (unless
+there are other changes inside subpatterns). If there is more than one setting
+of the same option at top level, the rightmost setting is used.
+</P>
+<P>
+If an option change occurs inside a subpattern, the effect is different. This
+is a change of behaviour in Perl 5.005. An option change inside a subpattern
+affects only that part of the subpattern that follows it, so
+</P>
+<P>
+<PRE>
+  (a(?i)b)c
+</PRE>
+</P>
+<P>
+matches abc and aBc and no other strings (assuming PCRE_CASELESS is not used).
+By this means, options can be made to have different settings in different
+parts of the pattern. Any changes made in one alternative do carry on
+into subsequent branches within the same subpattern. For example,
+</P>
+<P>
+<PRE>
+  (a(?i)b|c)
+</PRE>
+</P>
+<P>
+matches "ab", "aB", "c", and "C", even though when matching "C" the first
+branch is abandoned before the option setting. This is because the effects of
+option settings happen at compile time. There would be some very weird
+behaviour otherwise.
+</P>
+<P>
+The PCRE-specific options PCRE_UNGREEDY and PCRE_EXTRA can be changed in the
+same way as the Perl-compatible options by using the characters U and X
+respectively. The (?X) flag setting is special in that it must always occur
+earlier in the pattern than any of the additional features it turns on, even
+when it is at top level. It is best put at the start.
+</P>
+<LI><A NAME="SEC21" HREF="#TOC1">SUBPATTERNS</A>
+<P>
+Subpatterns are delimited by parentheses (round brackets), which can be nested.
+Marking part of a pattern as a subpattern does two things:
+</P>
+<P>
+1. It localizes a set of alternatives. For example, the pattern
+</P>
+<P>
+<PRE>
+  cat(aract|erpillar|)
+</PRE>
+</P>
+<P>
+matches one of the words "cat", "cataract", or "caterpillar". Without the
+parentheses, it would match "cataract", "erpillar" or the empty string.
+</P>
+<P>
+2. It sets up the subpattern as a capturing subpattern (as defined above).
+When the whole pattern matches, that portion of the subject string that matched
+the subpattern is passed back to the caller via the <I>ovector</I> argument of
+<B>pcre_exec()</B>. Opening parentheses are counted from left to right (starting
+from 1) to obtain the numbers of the capturing subpatterns.
+</P>
+<P>
+For example, if the string "the red king" is matched against the pattern
+</P>
+<P>
+<PRE>
+  the ((red|white) (king|queen))
+</PRE>
+</P>
+<P>
+the captured substrings are "red king", "red", and "king", and are numbered 1,
+2, and 3.
+</P>
+<P>
+The fact that plain parentheses fulfil two functions is not always helpful.
+There are often times when a grouping subpattern is required without a
+capturing requirement. If an opening parenthesis is followed by "?:", the
+subpattern does not do any capturing, and is not counted when computing the
+number of any subsequent capturing subpatterns. For example, if the string "the
+white queen" is matched against the pattern
+</P>
+<P>
+<PRE>
+  the ((?:red|white) (king|queen))
+</PRE>
+</P>
+<P>
+the captured substrings are "white queen" and "queen", and are numbered 1 and
+2. The maximum number of captured substrings is 99, and the maximum number of
+all subpatterns, both capturing and non-capturing, is 200.
+</P>
+<P>
+As a convenient shorthand, if any option settings are required at the start of
+a non-capturing subpattern, the option letters may appear between the "?" and
+the ":". Thus the two patterns
+</P>
+<P>
+<PRE>
+  (?i:saturday|sunday)
+  (?:(?i)saturday|sunday)
+</PRE>
+</P>
+<P>
+match exactly the same set of strings. Because alternative branches are tried
+from left to right, and options are not reset until the end of the subpattern
+is reached, an option setting in one branch does affect subsequent branches, so
+the above patterns match "SUNDAY" as well as "Saturday".
+</P>
+<LI><A NAME="SEC22" HREF="#TOC1">REPETITION</A>
+<P>
+Repetition is specified by quantifiers, which can follow any of the following
+items:
+</P>
+<P>
+<PRE>
+  a single character, possibly escaped
+  the . metacharacter
+  a character class
+  a back reference (see next section)
+  a parenthesized subpattern (unless it is an assertion - see below)
+</PRE>
+</P>
+<P>
+The general repetition quantifier specifies a minimum and maximum number of
+permitted matches, by giving the two numbers in curly brackets (braces),
+separated by a comma. The numbers must be less than 65536, and the first must
+be less than or equal to the second. For example:
+</P>
+<P>
+<PRE>
+  z{2,4}
+</PRE>
+</P>
+<P>
+matches "zz", "zzz", or "zzzz". A closing brace on its own is not a special
+character. If the second number is omitted, but the comma is present, there is
+no upper limit; if the second number and the comma are both omitted, the
+quantifier specifies an exact number of required matches. Thus
+</P>
+<P>
+<PRE>
+  [aeiou]{3,}
+</PRE>
+</P>
+<P>
+matches at least 3 successive vowels, but may match many more, while
+</P>
+<P>
+<PRE>
+  \d{8}
+</PRE>
+</P>
+<P>
+matches exactly 8 digits. An opening curly bracket that appears in a position
+where a quantifier is not allowed, or one that does not match the syntax of a
+quantifier, is taken as a literal character. For example, {,6} is not a
+quantifier, but a literal string of four characters.
+</P>
+<P>
+The quantifier {0} is permitted, causing the expression to behave as if the
+previous item and the quantifier were not present.
+</P>
+<P>
+For convenience (and historical compatibility) the three most common
+quantifiers have single-character abbreviations:
+</P>
+<P>
+<PRE>
+  *    is equivalent to {0,}
+  +    is equivalent to {1,}
+  ?    is equivalent to {0,1}
+</PRE>
+</P>
+<P>
+It is possible to construct infinite loops by following a subpattern that can
+match no characters with a quantifier that has no upper limit, for example:
+</P>
+<P>
+<PRE>
+  (a?)*
+</PRE>
+</P>
+<P>
+Earlier versions of Perl and PCRE used to give an error at compile time for
+such patterns. However, because there are cases where this can be useful, such
+patterns are now accepted, but if any repetition of the subpattern does in fact
+match no characters, the loop is forcibly broken.
+</P>
+<P>
+By default, the quantifiers are "greedy", that is, they match as much as
+possible (up to the maximum number of permitted times), without causing the
+rest of the pattern to fail. The classic example of where this gives problems
+is in trying to match comments in C programs. These appear between the
+sequences /* and */ and within the sequence, individual * and / characters may
+appear. An attempt to match C comments by applying the pattern
+</P>
+<P>
+<PRE>
+  /\*.*\*/
+</PRE>
+</P>
+<P>
+to the string
+</P>
+<P>
+<PRE>
+  /* first command */  not comment  /* second comment */
+</PRE>
+</P>
+<P>
+fails, because it matches the entire string due to the greediness of the .*
+item.
+</P>
+<P>
+However, if a quantifier is followed by a question mark, then it ceases to be
+greedy, and instead matches the minimum number of times possible, so the
+pattern
+</P>
+<P>
+<PRE>
+  /\*.*?\*/
+</PRE>
+</P>
+<P>
+does the right thing with the C comments. The meaning of the various
+quantifiers is not otherwise changed, just the preferred number of matches.
+Do not confuse this use of question mark with its use as a quantifier in its
+own right. Because it has two uses, it can sometimes appear doubled, as in
+</P>
+<P>
+<PRE>
+  \d??\d
+</PRE>
+</P>
+<P>
+which matches one digit by preference, but can match two if that is the only
+way the rest of the pattern matches.
+</P>
+<P>
+If the PCRE_UNGREEDY option is set (an option which is not available in Perl)
+then the quantifiers are not greedy by default, but individual ones can be made
+greedy by following them with a question mark. In other words, it inverts the
+default behaviour.
+</P>
+<P>
+When a parenthesized subpattern is quantified with a minimum repeat count that
+is greater than 1 or with a limited maximum, more store is required for the
+compiled pattern, in proportion to the size of the minimum or maximum.
+</P>
+<P>
+If a pattern starts with .* or .{0,} and the PCRE_DOTALL option (equivalent
+to Perl's /s) is set, thus allowing the . to match newlines, then the pattern
+is implicitly anchored, because whatever follows will be tried against every
+character position in the subject string, so there is no point in retrying the
+overall match at any position after the first. PCRE treats such a pattern as
+though it were preceded by \A. In cases where it is known that the subject
+string contains no newlines, it is worth setting PCRE_DOTALL when the pattern
+begins with .* in order to obtain this optimization, or alternatively using ^
+to indicate anchoring explicitly.
+</P>
+<P>
+When a capturing subpattern is repeated, the value captured is the substring
+that matched the final iteration. For example, after
+</P>
+<P>
+<PRE>
+  (tweedle[dume]{3}\s*)+
+</PRE>
+</P>
+<P>
+has matched "tweedledum tweedledee" the value of the captured substring is
+"tweedledee". However, if there are nested capturing subpatterns, the
+corresponding captured values may have been set in previous iterations. For
+example, after
+</P>
+<P>
+<PRE>
+  /(a|(b))+/
+</PRE>
+</P>
+<P>
+matches "aba" the value of the second captured substring is "b".
+</P>
+<LI><A NAME="SEC23" HREF="#TOC1">BACK REFERENCES</A>
+<P>
+Outside a character class, a backslash followed by a digit greater than 0 (and
+possibly further digits) is a back reference to a capturing subpattern earlier
+(i.e. to its left) in the pattern, provided there have been that many previous
+capturing left parentheses.
+</P>
+<P>
+However, if the decimal number following the backslash is less than 10, it is
+always taken as a back reference, and causes an error only if there are not
+that many capturing left parentheses in the entire pattern. In other words, the
+parentheses that are referenced need not be to the left of the reference for
+numbers less than 10. See the section entitled "Backslash" above for further
+details of the handling of digits following a backslash.
+</P>
+<P>
+A back reference matches whatever actually matched the capturing subpattern in
+the current subject string, rather than anything matching the subpattern
+itself. So the pattern
+</P>
+<P>
+<PRE>
+  (sens|respons)e and \1ibility
+</PRE>
+</P>
+<P>
+matches "sense and sensibility" and "response and responsibility", but not
+"sense and responsibility". If caseful matching is in force at the time of the
+back reference, then the case of letters is relevant. For example,
+</P>
+<P>
+<PRE>
+  ((?i)rah)\s+\1
+</PRE>
+</P>
+<P>
+matches "rah rah" and "RAH RAH", but not "RAH rah", even though the original
+capturing subpattern is matched caselessly.
+</P>
+<P>
+There may be more than one back reference to the same subpattern. If a
+subpattern has not actually been used in a particular match, then any back
+references to it always fail. For example, the pattern
+</P>
+<P>
+<PRE>
+  (a|(bc))\2
+</PRE>
+</P>
+<P>
+always fails if it starts to match "a" rather than "bc". Because there may be
+up to 99 back references, all digits following the backslash are taken
+as part of a potential back reference number. If the pattern continues with a
+digit character, then some delimiter must be used to terminate the back
+reference. If the PCRE_EXTENDED option is set, this can be whitespace.
+Otherwise an empty comment can be used.
+</P>
+<P>
+A back reference that occurs inside the parentheses to which it refers fails
+when the subpattern is first used, so, for example, (a\1) never matches.
+However, such references can be useful inside repeated subpatterns. For
+example, the pattern
+</P>
+<P>
+<PRE>
+  (a|b\1)+
+</PRE>
+</P>
+<P>
+matches any number of "a"s and also "aba", "ababaa" etc. At each iteration of
+the subpattern, the back reference matches the character string corresponding
+to the previous iteration. In order for this to work, the pattern must be such
+that the first iteration does not need to match the back reference. This can be
+done using alternation, as in the example above, or by a quantifier with a
+minimum of zero.
+</P>
+<LI><A NAME="SEC24" HREF="#TOC1">ASSERTIONS</A>
+<P>
+An assertion is a test on the characters following or preceding the current
+matching point that does not actually consume any characters. The simple
+assertions coded as \b, \B, \A, \Z, \z, ^ and $ are described above. More
+complicated assertions are coded as subpatterns. There are two kinds: those
+that look ahead of the current position in the subject string, and those that
+look behind it.
+</P>
+<P>
+An assertion subpattern is matched in the normal way, except that it does not
+cause the current matching position to be changed. Lookahead assertions start
+with (?= for positive assertions and (?! for negative assertions. For example,
+</P>
+<P>
+<PRE>
+  \w+(?=;)
+</PRE>
+</P>
+<P>
+matches a word followed by a semicolon, but does not include the semicolon in
+the match, and
+</P>
+<P>
+<PRE>
+  foo(?!bar)
+</PRE>
+</P>
+<P>
+matches any occurrence of "foo" that is not followed by "bar". Note that the
+apparently similar pattern
+</P>
+<P>
+<PRE>
+  (?!foo)bar
+</PRE>
+</P>
+<P>
+does not find an occurrence of "bar" that is preceded by something other than
+"foo"; it finds any occurrence of "bar" whatsoever, because the assertion
+(?!foo) is always true when the next three characters are "bar". A
+lookbehind assertion is needed to achieve this effect.
+</P>
+<P>
+Lookbehind assertions start with (?&#60;= for positive assertions and (?&#60;! for
+negative assertions. For example,
+</P>
+<P>
+<PRE>
+  (?&#60;!foo)bar
+</PRE>
+</P>
+<P>
+does find an occurrence of "bar" that is not preceded by "foo". The contents of
+a lookbehind assertion are restricted such that all the strings it matches must
+have a fixed length. However, if there are several alternatives, they do not
+all have to have the same fixed length. Thus
+</P>
+<P>
+<PRE>
+  (?&#60;=bullock|donkey)
+</PRE>
+</P>
+<P>
+is permitted, but
+</P>
+<P>
+<PRE>
+  (?&#60;!dogs?|cats?)
+</PRE>
+</P>
+<P>
+causes an error at compile time. Branches that match different length strings
+are permitted only at the top level of a lookbehind assertion. This is an
+extension compared with Perl 5.005, which requires all branches to match the
+same length of string. An assertion such as
+</P>
+<P>
+<PRE>
+  (?&#60;=ab(c|de))
+</PRE>
+</P>
+<P>
+is not permitted, because its single top-level branch can match two different
+lengths, but it is acceptable if rewritten to use two top-level branches:
+</P>
+<P>
+<PRE>
+  (?&#60;=abc|abde)
+</PRE>
+</P>
+<P>
+The implementation of lookbehind assertions is, for each alternative, to
+temporarily move the current position back by the fixed width and then try to
+match. If there are insufficient characters before the current position, the
+match is deemed to fail. Lookbehinds in conjunction with once-only subpatterns
+can be particularly useful for matching at the ends of strings; an example is
+given at the end of the section on once-only subpatterns.
+</P>
+<P>
+Several assertions (of any sort) may occur in succession. For example,
+</P>
+<P>
+<PRE>
+  (?&#60;=\d{3})(?&#60;!999)foo
+</PRE>
+</P>
+<P>
+matches "foo" preceded by three digits that are not "999". Notice that each of
+the assertions is applied independently at the same point in the subject
+string. First there is a check that the previous three characters are all
+digits, then there is a check that the same three characters are not "999".
+This pattern does <I>not</I> match "foo" preceded by six characters, the first
+of which are digits and the last three of which are not "999". For example, it
+doesn't match "123abcfoo". A pattern to do that is
+</P>
+<P>
+<PRE>
+  (?&#60;=\d{3}...)(?&#60;!999)foo
+</PRE>
+</P>
+<P>
+This time the first assertion looks at the preceding six characters, checking
+that the first three are digits, and then the second assertion checks that the
+preceding three characters are not "999".
+</P>
+<P>
+Assertions can be nested in any combination. For example,
+</P>
+<P>
+<PRE>
+  (?&#60;=(?&#60;!foo)bar)baz
+</PRE>
+</P>
+<P>
+matches an occurrence of "baz" that is preceded by "bar" which in turn is not
+preceded by "foo", while
+</P>
+<P>
+<PRE>
+  (?&#60;=\d{3}(?!999)...)foo
+</PRE>
+</P>
+<P>
+is another pattern which matches "foo" preceded by three digits and any three
+characters that are not "999".
+</P>
+<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.
+</P>
+<P>
+Assertions count towards the maximum of 200 parenthesized subpatterns.
+</P>
+<LI><A NAME="SEC25" HREF="#TOC1">ONCE-ONLY SUBPATTERNS</A>
+<P>
+With both maximizing and minimizing repetition, failure of what follows
+normally causes the repeated item to be re-evaluated to see if a different
+number of repeats allows the rest of the pattern to match. Sometimes it is
+useful to prevent this, either to change the nature of the match, or to cause
+it fail earlier than it otherwise might, when the author of the pattern knows
+there is no point in carrying on.
+</P>
+<P>
+Consider, for example, the pattern \d+foo when applied to the subject line
+</P>
+<P>
+<PRE>
+  123456bar
+</PRE>
+</P>
+<P>
+After matching all 6 digits and then failing to match "foo", the normal
+action of the matcher is to try again with only 5 digits matching the \d+
+item, and then with 4, and so on, before ultimately failing. Once-only
+subpatterns provide the means for specifying that once a portion of the pattern
+has matched, it is not to be re-evaluated in this way, so the matcher would
+give up immediately on failing to match "foo" the first time. The notation is
+another kind of special parenthesis, starting with (?&#62; as in this example:
+</P>
+<P>
+<PRE>
+  (?&#62;\d+)bar
+</PRE>
+</P>
+<P>
+This kind of parenthesis "locks up" the  part of the pattern it contains once
+it has matched, and a failure further into the pattern is prevented from
+backtracking into it. Backtracking past it to previous items, however, works as
+normal.
+</P>
+<P>
+An alternative description is that a subpattern of this type matches the string
+of characters that an identical standalone pattern would match, if anchored at
+the current point in the subject string.
+</P>
+<P>
+Once-only subpatterns are not capturing subpatterns. Simple cases such as the
+above example can be thought of as a maximizing repeat that must swallow
+everything it can. So, while both \d+ and \d+? are prepared to adjust the
+number of digits they match in order to make the rest of the pattern match,
+(?&#62;\d+) can only match an entire sequence of digits.
+</P>
+<P>
+This construction can of course contain arbitrarily complicated subpatterns,
+and it can be nested.
+</P>
+<P>
+Once-only subpatterns can be used in conjunction with lookbehind assertions to
+specify efficient matching at the end of the subject string. Consider a simple
+pattern such as
+</P>
+<P>
+<PRE>
+  abcd$
+</PRE>
+</P>
+<P>
+when applied to a long string which does not match. Because matching proceeds
+from left to right, PCRE will look for each "a" in the subject and then see if
+what follows matches the rest of the pattern. If the pattern is specified as
+</P>
+<P>
+<PRE>
+  ^.*abcd$
+</PRE>
+</P>
+<P>
+then the initial .* matches the entire string at first, but when this fails
+(because there is no following "a"), it backtracks to match all but the last
+character, then all but the last two characters, and so on. Once again the
+search for "a" covers the entire string, from right to left, so we are no
+better off. However, if the pattern is written as
+</P>
+<P>
+<PRE>
+  ^(?&#62;.*)(?&#60;=abcd)
+</PRE>
+</P>
+<P>
+then there can be no backtracking for the .* item; it can match only the entire
+string. The subsequent lookbehind assertion does a single test on the last four
+characters. If it fails, the match fails immediately. For long strings, this
+approach makes a significant difference to the processing time.
+</P>
+<P>
+When a pattern contains an unlimited repeat inside a subpattern that can itself
+be repeated an unlimited number of times, the use of a once-only subpattern is
+the only way to avoid some failing matches taking a very long time indeed.
+The pattern
+</P>
+<P>
+<PRE>
+  (\D+|&#60;\d+&#62;)*[!?]
+</PRE>
+</P>
+<P>
+matches an unlimited number of substrings that either consist of non-digits, or
+digits enclosed in &#60;&#62;, followed by either ! or ?. When it matches, it runs
+quickly. However, if it is applied to
+</P>
+<P>
+<PRE>
+  aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+</PRE>
+</P>
+<P>
+it takes a long time before reporting failure. This is because the string can
+be divided between the two repeats in a large number of ways, and all have to
+be tried. (The example used [!?] rather than a single character at the end,
+because both PCRE and Perl have an optimization that allows for fast failure
+when a single character is used. They remember the last single character that
+is required for a match, and fail early if it is not present in the string.)
+If the pattern is changed to
+</P>
+<P>
+<PRE>
+  ((?&#62;\D+)|&#60;\d+&#62;)*[!?]
+</PRE>
+</P>
+<P>
+sequences of non-digits cannot be broken, and failure happens quickly.
+</P>
+<LI><A NAME="SEC26" HREF="#TOC1">CONDITIONAL SUBPATTERNS</A>
+<P>
+It is possible to cause the matching process to obey a subpattern
+conditionally or to choose between two alternative subpatterns, depending on
+the result of an assertion, or whether a previous capturing subpattern matched
+or not. The two possible forms of conditional subpattern are
+</P>
+<P>
+<PRE>
+  (?(condition)yes-pattern)
+  (?(condition)yes-pattern|no-pattern)
+</PRE>
+</P>
+<P>
+If the condition is satisfied, the yes-pattern is used; otherwise the
+no-pattern (if present) is used. If there are more than two alternatives in the
+subpattern, a compile-time error occurs.
+</P>
+<P>
+There are two kinds of condition. If the text between the parentheses consists
+of a sequence of digits, then the condition is satisfied if the capturing
+subpattern of that number has previously matched. Consider the following
+pattern, which contains non-significant white space to make it more readable
+(assume the PCRE_EXTENDED option) and to divide it into three parts for ease
+of discussion:
+</P>
+<P>
+<PRE>
+  ( \( )?    [^()]+    (?(1) \) )
+</PRE>
+</P>
+<P>
+The first part matches an optional opening parenthesis, and if that
+character is present, sets it as the first captured substring. The second part
+matches one or more characters that are not parentheses. The third part is a
+conditional subpattern that tests whether the first set of parentheses matched
+or not. If they did, that is, if subject started with an opening parenthesis,
+the condition is true, and so the yes-pattern is executed and a closing
+parenthesis is required. Otherwise, since no-pattern is not present, the
+subpattern matches nothing. In other words, this pattern matches a sequence of
+non-parentheses, optionally enclosed in parentheses.
+</P>
+<P>
+If the condition is not a sequence of digits, it must be an assertion. This may
+be a positive or negative lookahead or lookbehind assertion. Consider this
+pattern, again containing non-significant white space, and with the two
+alternatives on the second line:
+</P>
+<P>
+<PRE>
+  (?(?=[^a-z]*[a-z])
+  \d{2}-[a-z]{3}-\d{2}  |  \d{2}-\d{2}-\d{2} )
+</PRE>
+</P>
+<P>
+The condition is a positive lookahead assertion that matches an optional
+sequence of non-letters followed by a letter. In other words, it tests for the
+presence of at least one letter in the subject. If a letter is found, the
+subject is matched against the first alternative; otherwise it is matched
+against the second. This pattern matches strings in one of the two forms
+dd-aaa-dd or dd-dd-dd, where aaa are letters and dd are digits.
+</P>
+<LI><A NAME="SEC27" HREF="#TOC1">COMMENTS</A>
+<P>
+The sequence (?# marks the start of a comment which continues up to the next
+closing parenthesis. Nested parentheses are not permitted. The characters
+that make up a comment play no part in the pattern matching at all.
+</P>
+<P>
+If the PCRE_EXTENDED option is set, an unescaped # character outside a
+character class introduces a comment that continues up to the next newline
+character in the pattern.
+</P>
+<LI><A NAME="SEC28" HREF="#TOC1">RECURSIVE PATTERNS</A>
+<P>
+Consider the problem of matching a string in parentheses, allowing for
+unlimited nested parentheses. Without the use of recursion, the best that can
+be done is to use a pattern that matches up to some fixed depth of nesting. It
+is not possible to handle an arbitrary nesting depth. Perl 5.6 has provided an
+experimental facility that allows regular expressions to recurse (amongst other
+things). It does this by interpolating Perl code in the expression at run time,
+and the code can refer to the expression itself. A Perl pattern to solve the
+parentheses problem can be created like this:
+</P>
+<P>
+<PRE>
+  $re = qr{\( (?: (?&#62;[^()]+) | (?p{$re}) )* \)}x;
+</PRE>
+</P>
+<P>
+The (?p{...}) item interpolates Perl code at run time, and in this case refers
+recursively to the pattern in which it appears. Obviously, PCRE cannot support
+the interpolation of Perl code. Instead, the special item (?R) is provided for
+the specific case of recursion. This PCRE pattern solves the parentheses
+problem (assume the PCRE_EXTENDED option is set so that white space is
+ignored):
+</P>
+<P>
+<PRE>
+  \( ( (?&#62;[^()]+) | (?R) )* \)
+</PRE>
+</P>
+<P>
+First it matches an opening parenthesis. Then it matches any number of
+substrings which can either be a sequence of non-parentheses, or a recursive
+match of the pattern itself (i.e. a correctly parenthesized substring). Finally
+there is a closing parenthesis.
+</P>
+<P>
+This particular example pattern contains nested unlimited repeats, and so the
+use of a once-only subpattern for matching strings of non-parentheses is
+important when applying the pattern to strings that do not match. For example,
+when it is applied to
+</P>
+<P>
+<PRE>
+  (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
+</PRE>
+</P>
+<P>
+it yields "no match" quickly. However, if a once-only subpattern is not used,
+the match runs for a very long time indeed because there are so many different
+ways the + and * repeats can carve up the subject, and all have to be tested
+before failure can be reported.
+</P>
+<P>
+The values set for any capturing subpatterns are those from the outermost level
+of the recursion at which the subpattern value is set. If the pattern above is
+matched against
+</P>
+<P>
+<PRE>
+  (ab(cd)ef)
+</PRE>
+</P>
+<P>
+the value for the capturing parentheses is "ef", which is the last value taken
+on at the top level. If additional parentheses are added, giving
+</P>
+<P>
+<PRE>
+  \( ( ( (?&#62;[^()]+) | (?R) )* ) \)
+     ^                        ^
+     ^                        ^
+</PRE>
+then the string they capture is "ab(cd)ef", the contents of the top level
+parentheses. If there are more than 15 capturing parentheses in a pattern, PCRE
+has to obtain extra memory to store data during a recursion, which it does by
+using <B>pcre_malloc</B>, freeing it via <B>pcre_free</B> afterwards. If no
+memory can be obtained, it saves data for the first 15 capturing parentheses
+only, as there is no way to give an out-of-memory error from within a
+recursion.
+</P>
+<LI><A NAME="SEC29" HREF="#TOC1">PERFORMANCE</A>
+<P>
+Certain items that may appear in patterns are more efficient than others. It is
+more efficient to use a character class like [aeiou] than a set of alternatives
+such as (a|e|i|o|u). In general, the simplest construction that provides the
+required behaviour is usually the most efficient. Jeffrey Friedl's book
+contains a lot of discussion about optimizing regular expressions for efficient
+performance.
+</P>
+<P>
+When a pattern begins with .* and the PCRE_DOTALL option is set, the pattern is
+implicitly anchored by PCRE, since it can match only at the start of a subject
+string. However, if PCRE_DOTALL is not set, PCRE cannot make this optimization,
+because the . metacharacter does not then match a newline, and if the subject
+string contains newlines, the pattern may match from the character immediately
+following one of them instead of from the very start. For example, the pattern
+</P>
+<P>
+<PRE>
+  (.*) second
+</PRE>
+</P>
+<P>
+matches the subject "first\nand second" (where \n stands for a newline
+character) with the first captured substring being "and". In order to do this,
+PCRE has to retry the match starting after every newline in the subject.
+</P>
+<P>
+If you are using such a pattern with subject strings that do not contain
+newlines, the best performance is obtained by setting PCRE_DOTALL, or starting
+the pattern with ^.* to indicate explicit anchoring. That saves PCRE from
+having to scan along the subject looking for a newline to restart at.
+</P>
+<P>
+Beware of patterns that contain nested indefinite repeats. These can take a
+long time to run when applied to a string that does not match. Consider the
+pattern fragment
+</P>
+<P>
+<PRE>
+  (a+)*
+</PRE>
+</P>
+<P>
+This can match "aaaa" in 33 different ways, and this number increases very
+rapidly as the string gets longer. (The * repeat can match 0, 1, 2, 3, or 4
+times, and for each of those cases other than 0, the + repeats can match
+different numbers of times.) When the remainder of the pattern is such that the
+entire match is going to fail, PCRE has in principle to try every possible
+variation, and this can take an extremely long time.
+</P>
+<P>
+An optimization catches some of the more simple cases such as
+</P>
+<P>
+<PRE>
+  (a+)*b
+</PRE>
+</P>
+<P>
+where a literal character follows. Before embarking on the standard matching
+procedure, PCRE checks that there is a "b" later in the subject string, and if
+there is not, it fails the match immediately. However, when there is no
+following literal this optimization cannot be used. You can see the difference
+by comparing the behaviour of
+</P>
+<P>
+<PRE>
+  (a+)*\d
+</PRE>
+</P>
+<P>
+with the pattern above. The former gives a failure almost instantly when
+applied to a whole line of "a" characters, whereas the latter takes an
+appreciable time with strings longer than about 20 characters.
+</P>
+<LI><A NAME="SEC30" HREF="#TOC1">AUTHOR</A>
+<P>
+Philip Hazel &#60;ph10@cam.ac.uk&#62;
+<BR>
+University Computing Service,
+<BR>
+New Museums Site,
+<BR>
+Cambridge CB2 3QG, England.
+<BR>
+Phone: +44 1223 334714
+</P>
+<P>
+Last updated: 27 January 2000
+<BR>
+Copyright (c) 1997-2000 University of Cambridge.
diff --git a/ext/pcre/pcrelib/doc/pcre.txt b/ext/pcre/pcrelib/doc/pcre.txt
new file mode 100644 (file)
index 0000000..f28ee99
--- /dev/null
@@ -0,0 +1,1978 @@
+NAME
+     pcre - Perl-compatible regular expressions.
+
+
+
+SYNOPSIS
+     #include <pcre.h>
+
+     pcre *pcre_compile(const char *pattern, int options,
+          const char **errptr, int *erroffset,
+          const unsigned char *tableptr);
+
+     pcre_extra *pcre_study(const pcre *code, int options,
+          const char **errptr);
+
+     int pcre_exec(const pcre *code, const pcre_extra *extra,
+          const char *subject, int length, int startoffset,
+          int options, int *ovector, int ovecsize);
+
+     int pcre_copy_substring(const char *subject, int *ovector,
+          int stringcount, int stringnumber, char *buffer,
+          int buffersize);
+
+     int pcre_get_substring(const char *subject, int *ovector,
+          int stringcount, int stringnumber,
+          const char **stringptr);
+
+     int pcre_get_substring_list(const char *subject,
+          int *ovector, int stringcount, const char ***listptr);
+
+     const unsigned char *pcre_maketables(void);
+
+     int pcre_fullinfo(const pcre *code, const pcre_extra *extra,
+          int what, void *where);
+
+     int pcre_info(const pcre *code, int *optptr, *firstcharptr);
+
+     char *pcre_version(void);
+
+     void *(*pcre_malloc)(size_t);
+
+     void (*pcre_free)(void *);
+
+
+
+
+DESCRIPTION
+     The PCRE library is a set of functions that implement  regu-
+     lar  expression  pattern  matching using the same syntax and
+     semantics as Perl  5,  with  just  a  few  differences  (see
+     below).  The  current  implementation  corresponds  to  Perl
+     5.005, with some additional features from the Perl  develop-
+     ment release.
+
+     PCRE has its own native API,  which  is  described  in  this
+     document.  There  is  also  a  set of wrapper functions that
+     correspond to the POSIX regular expression API.   These  are
+     described in the pcreposix documentation.
+
+     The native API function prototypes are defined in the header
+     file  pcre.h,  and  on  Unix  systems  the library itself is
+     called libpcre.a, so can be accessed by adding -lpcre to the
+     command  for  linking  an  application  which  calls it. The
+     header file defines the macros PCRE_MAJOR and PCRE_MINOR  to
+     contain the major and minor release numbers for the library.
+     Applications can use these to include support for  different
+     releases.
+
+     The functions pcre_compile(), pcre_study(), and  pcre_exec()
+     are  used  for  compiling  and matching regular expressions,
+     while   pcre_copy_substring(),   pcre_get_substring(),   and
+     pcre_get_substring_list()   are  convenience  functions  for
+     extracting  captured  substrings  from  a  matched   subject
+     string.  The function pcre_maketables() is used (optionally)
+     to build a set of character tables in the current locale for
+     passing to pcre_compile().
+
+     The function pcre_fullinfo() is used to find out information
+     about a compiled pattern; pcre_info() is an obsolete version
+     which returns only some of the available information, but is
+     retained   for   backwards   compatibility.    The  function
+     pcre_version() returns a pointer to a string containing  the
+     version of PCRE and its date of release.
+
+     The global variables  pcre_malloc  and  pcre_free  initially
+     contain the entry points of the standard malloc() and free()
+     functions respectively. PCRE  calls  the  memory  management
+     functions  via  these  variables,  so  a calling program can
+     replace them if it  wishes  to  intercept  the  calls.  This
+     should be done before calling any PCRE functions.
+
+
+
+MULTI-THREADING
+     The PCRE functions can be used in  multi-threading  applica-
+     tions, with the proviso that the memory management functions
+     pointed to by pcre_malloc and pcre_free are  shared  by  all
+     threads.
+
+     The compiled form of a regular  expression  is  not  altered
+     during  matching, so the same compiled pattern can safely be
+     used by several threads at once.
+
+
+
+
+COMPILING A PATTERN
+     The function pcre_compile() is called to compile  a  pattern
+     into  an internal form. The pattern is a C string terminated
+     by a binary zero, and is passed in the argument  pattern.  A
+     pointer  to  a  single  block of memory that is obtained via
+     pcre_malloc is returned. This contains the compiled code and
+     related data. The pcre type is defined for this for conveni-
+     ence, but in fact pcre is just a typedef for void, since the
+     contents  of  the block are not externally defined. It is up
+     to the caller to free  the  memory  when  it  is  no  longer
+     required.
+
+     The size of a compiled pattern is  roughly  proportional  to
+     the length of the pattern string, except that each character
+     class (other than those containing just a single  character,
+     negated  or  not)  requires 33 bytes, and repeat quantifiers
+     with a minimum greater than one or a bounded  maximum  cause
+     the  relevant  portions of the compiled pattern to be repli-
+     cated.
+
+     The options argument contains independent bits  that  affect
+     the  compilation.  It  should  be  zero  if  no  options are
+     required. Some of the options, in particular, those that are
+     compatible  with Perl, can also be set and unset from within
+     the pattern (see the detailed description of regular expres-
+     sions below). For these options, the contents of the options
+     argument specifies their initial settings at  the  start  of
+     compilation  and  execution. The PCRE_ANCHORED option can be
+     set at the time of matching as well as at compile time.
+
+     If errptr is NULL, pcre_compile() returns NULL  immediately.
+     Otherwise, if compilation of a pattern fails, pcre_compile()
+     returns NULL, and sets the variable pointed to by errptr  to
+     point  to a textual error message. The offset from the start
+     of  the  pattern  to  the  character  where  the  error  was
+     discovered   is   placed  in  the  variable  pointed  to  by
+     erroffset, which must not be NULL. If it  is,  an  immediate
+     error is given.
+
+     If the final  argument,  tableptr,  is  NULL,  PCRE  uses  a
+     default  set  of character tables which are built when it is
+     compiled, using the default C  locale.  Otherwise,  tableptr
+     must  be  the result of a call to pcre_maketables(). See the
+     section on locale support below.
+
+     The following option bits are defined in the header file:
+
+       PCRE_ANCHORED
+
+     If this bit is set, the pattern is forced to be  "anchored",
+     that is, it is constrained to match only at the start of the
+     string which is being searched (the "subject string").  This
+     effect can also be achieved by appropriate constructs in the
+     pattern itself, which is the only way to do it in Perl.
+
+       PCRE_CASELESS
+
+     If this bit is set, letters in the pattern match both  upper
+     and  lower  case  letters.  It  is  equivalent  to Perl's /i
+     option.
+
+       PCRE_DOLLAR_ENDONLY
+
+     If this bit is set, a dollar metacharacter  in  the  pattern
+     matches  only at the end of the subject string. Without this
+     option, a dollar also matches immediately before  the  final
+     character  if it is a newline (but not before any other new-
+     lines).  The  PCRE_DOLLAR_ENDONLY  option  is   ignored   if
+     PCRE_MULTILINE is set. There is no equivalent to this option
+     in Perl.
+
+       PCRE_DOTALL
+
+     If this bit is  set,  a  dot  metacharater  in  the  pattern
+     matches all characters, including newlines. Without it, new-
+     lines are excluded. This option is equivalent to  Perl's  /s
+     option.  A negative class such as [^a] always matches a new-
+     line character, independent of the setting of this option.
+
+       PCRE_EXTENDED
+
+     If this bit is set, whitespace data characters in  the  pat-
+     tern  are  totally  ignored  except when escaped or inside a
+     character class, and characters between an unescaped #  out-
+     side  a  character  class  and  the  next newline character,
+     inclusive, are also ignored. This is equivalent to Perl's /x
+     option,  and  makes  it  possible to include comments inside
+     complicated patterns. Note, however, that this applies  only
+     to  data  characters. Whitespace characters may never appear
+     within special character sequences in a pattern, for example
+     within  the sequence (?( which introduces a conditional sub-
+     pattern.
+
+       PCRE_EXTRA
+
+     This option was invented in  order  to  turn  on  additional
+     functionality of PCRE that is incompatible with Perl, but it
+     is currently of very little use. When set, any backslash  in
+     a  pattern  that is followed by a letter that has no special
+     meaning causes an error, thus reserving  these  combinations
+     for  future  expansion.  By default, as in Perl, a backslash
+     followed by a letter with no special meaning is treated as a
+     literal.  There  are at present no other features controlled
+     by this option. It can also be set by a (?X) option  setting
+     within a pattern.
+
+       PCRE_MULTILINE
+
+     By default, PCRE treats the subject string as consisting  of
+     a  single "line" of characters (even if it actually contains
+     several newlines). The "start  of  line"  metacharacter  (^)
+     matches  only  at the start of the string, while the "end of
+     line" metacharacter ($) matches  only  at  the  end  of  the
+     string,    or   before   a   terminating   newline   (unless
+     PCRE_DOLLAR_ENDONLY is set). This is the same as Perl.
+
+     When PCRE_MULTILINE it is set, the "start of line" and  "end
+     of  line"  constructs match immediately following or immedi-
+     ately before any newline  in  the  subject  string,  respec-
+     tively,  as  well  as  at  the  very  start and end. This is
+     equivalent to Perl's /m option. If there are no "\n" charac-
+     ters  in  a subject string, or no occurrences of ^ or $ in a
+     pattern, setting PCRE_MULTILINE has no effect.
+
+       PCRE_UNGREEDY
+
+     This option inverts the "greediness" of the  quantifiers  so
+     that  they  are  not greedy by default, but become greedy if
+     followed by "?". It is not compatible with Perl. It can also
+     be set by a (?U) option setting within the pattern.
+
+
+
+STUDYING A PATTERN
+     When a pattern is going to be  used  several  times,  it  is
+     worth  spending  more time analyzing it in order to speed up
+     the time taken for matching. The function pcre_study() takes
+     a  pointer  to a compiled pattern as its first argument, and
+     returns a  pointer  to  a  pcre_extra  block  (another  void
+     typedef)  containing  additional  information about the pat-
+     tern; this can be passed to pcre_exec().  If  no  additional
+     information is available, NULL is returned.
+
+     The second argument contains option  bits.  At  present,  no
+     options  are  defined  for  pcre_study(),  and this argument
+     should always be zero.
+
+     The third argument for pcre_study() is a pointer to an error
+     message. If studying succeeds (even if no data is returned),
+     the variable it points to  is  set  to  NULL.  Otherwise  it
+     points to a textual error message.
+
+     At present, studying a  pattern  is  useful  only  for  non-
+     anchored  patterns  that do not have a single fixed starting
+     character. A  bitmap  of  possible  starting  characters  is
+     created.
+
+
+
+LOCALE SUPPORT
+     PCRE handles caseless matching, and determines whether char-
+     acters  are  letters, digits, or whatever, by reference to a
+     set of tables. The library contains a default set of  tables
+     which  is  created in the default C locale when PCRE is com-
+     piled.  This  is   used   when   the   final   argument   of
+     pcre_compile()  is NULL, and is sufficient for many applica-
+     tions.
+
+     An alternative set of tables can, however, be supplied. Such
+     tables  are built by calling the pcre_maketables() function,
+     which has no arguments, in the relevant locale.  The  result
+     can  then be passed to pcre_compile() as often as necessary.
+     For example, to build and use tables  that  are  appropriate
+     for  the French locale (where accented characters with codes
+     greater than 128 are treated as letters), the following code
+     could be used:
+
+       setlocale(LC_CTYPE, "fr");
+       tables = pcre_maketables();
+       re = pcre_compile(..., tables);
+
+     The  tables  are  built  in  memory  that  is  obtained  via
+     pcre_malloc.  The  pointer that is passed to pcre_compile is
+     saved with the compiled pattern, and  the  same  tables  are
+     used  via this pointer by pcre_study() and pcre_exec(). Thus
+     for any single pattern, compilation, studying  and  matching
+     all happen in the same locale, but different patterns can be
+     compiled in different locales. It is the caller's  responsi-
+     bility  to  ensure  that  the  memory  containing the tables
+     remains available for as long as it is needed.
+
+
+
+INFORMATION ABOUT A PATTERN
+     The pcre_fullinfo() function  returns  information  about  a
+     compiled pattern. It replaces the obsolete pcre_info() func-
+     tion, which is nevertheless retained for backwards compabil-
+     ity (and is documented below).
+
+     The first argument for pcre_fullinfo() is a pointer  to  the
+     compiled  pattern.  The  second  argument  is  the result of
+     pcre_study(), or NULL if the pattern was  not  studied.  The
+     third  argument  specifies  which  piece  of  information is
+     required, while the fourth argument is a pointer to a  vari-
+     able  to receive the data. The yield of the function is zero
+     for success, or one of the following negative numbers:
+
+       PCRE_ERROR_NULL       the argument code was NULL
+                             the argument where was NULL
+       PCRE_ERROR_BADMAGIC   the "magic number" was not found
+       PCRE_ERROR_BADOPTION  the value of what was invalid
+
+     The possible values for the third argument  are  defined  in
+     pcre.h, and are as follows:
+
+       PCRE_INFO_OPTIONS
+
+     Return a copy of the options with which the pattern was com-
+     piled.  The fourth argument should point to au unsigned long
+     int variable. These option bits are those specified  in  the
+     call  to  pcre_compile(),  modified  by any top-level option
+     settings  within  the   pattern   itself,   and   with   the
+     PCRE_ANCHORED  bit  forcibly  set if the form of the pattern
+     implies that it can match only at the  start  of  a  subject
+     string.
+
+       PCRE_INFO_SIZE
+
+     Return the size of the compiled pattern, that is, the  value
+     that  was  passed as the argument to pcre_malloc() when PCRE
+     was getting memory in which to place the compiled data.  The
+     fourth argument should point to a size_t variable.
+
+       PCRE_INFO_CAPTURECOUNT
+
+     Return the number of capturing subpatterns in  the  pattern.
+     The fourth argument should point to an int variable.
+
+       PCRE_INFO_BACKREFMAX
+
+     Return the number of the highest back reference in the  pat-
+     tern.  The  fourth argument should point to an int variable.
+     Zero is returned if there are no back references.
+
+       PCRE_INFO_FIRSTCHAR
+
+     Return information about the first character of any  matched
+     string,  for  a  non-anchored  pattern.  If there is a fixed
+     first   character,   e.g.   from   a   pattern    such    as
+     (cat|cow|coyote), then it is returned in the integer pointed
+     to by where. Otherwise, if either
+
+     (a) the pattern was compiled with the PCRE_MULTILINE option,
+     and every branch starts with "^", or
+
+     (b) every  branch  of  the  pattern  starts  with  ".*"  and
+     PCRE_DOTALL is not set (if it were set, the pattern would be
+     anchored),
+
+     then -1 is returned, indicating  that  the  pattern  matches
+     only  at  the  start  of  a subject string or after any "\n"
+     within the string. Otherwise -2 is  returned.  For  anchored
+     patterns, -2 is returned.
+
+       PCRE_INFO_FIRSTTABLE
+
+     If the pattern was studied, and this resulted  in  the  con-
+     struction of a 256-bit table indicating a fixed set of char-
+     acters for the first character in  any  matching  string,  a
+     pointer   to  the  table  is  returned.  Otherwise  NULL  is
+     returned. The fourth argument should point  to  an  unsigned
+     char * variable.
+
+       PCRE_INFO_LASTLITERAL
+
+     For a non-anchored pattern, return the value of  the  right-
+     most  literal  character  which  must  exist  in any matched
+     string, other than at its start. The fourth argument  should
+     point  to an int variable. If there is no such character, or
+     if the pattern is anchored, -1 is returned. For example, for
+     the pattern /a\d+z\d+/ the returned value is 'z'.
+
+     The pcre_info() function is now obsolete because its  inter-
+     face  is  too  restrictive  to return all the available data
+     about  a  compiled  pattern.   New   programs   should   use
+     pcre_fullinfo()  instead.  The  yield  of pcre_info() is the
+     number of capturing subpatterns, or  one  of  the  following
+     negative numbers:
+
+       PCRE_ERROR_NULL       the argument code was NULL
+       PCRE_ERROR_BADMAGIC   the "magic number" was not found
+
+     If the optptr argument is not NULL, a copy  of  the  options
+     with which the pattern was compiled is placed in the integer
+     it points to (see PCRE_INFO_OPTIONS above).
+
+     If the pattern is not anchored and the firstcharptr argument
+     is  not  NULL, it is used to pass back information about the
+     first    character    of    any    matched    string    (see
+     PCRE_INFO_FIRSTCHAR above).
+
+
+
+MATCHING A PATTERN
+     The function pcre_exec() is called to match a subject string
+     against  a pre-compiled pattern, which is passed in the code
+     argument. If the pattern has been studied, the result of the
+     study should be passed in the extra argument. Otherwise this
+     must be NULL.
+
+     The PCRE_ANCHORED option can be passed in the options  argu-
+     ment,  whose unused bits must be zero. However, if a pattern
+     was  compiled  with  PCRE_ANCHORED,  or  turned  out  to  be
+     anchored  by  virtue  of  its  contents,  it  cannot be made
+     unachored at matching time.
+
+     There are also three further options that can be set only at
+     matching time:
+
+       PCRE_NOTBOL
+
+     The first character of the string is not the beginning of  a
+     line,  so  the  circumflex  metacharacter  should  not match
+     before it. Setting this without PCRE_MULTILINE  (at  compile
+     time) causes circumflex never to match.
+
+       PCRE_NOTEOL
+
+     The end of the string is not the end of a line, so the  dol-
+     lar  metacharacter should not match it nor (except in multi-
+     line mode) a newline immediately  before  it.  Setting  this
+     without PCRE_MULTILINE (at compile time) causes dollar never
+     to match.
+
+       PCRE_NOTEMPTY
+
+     An empty string is not considered to be  a  valid  match  if
+     this  option  is  set. If there are alternatives in the pat-
+     tern, they are tried. If  all  the  alternatives  match  the
+     empty  string,  the  entire match fails. For example, if the
+     pattern
+
+       a?b?
+
+     is applied to a string not beginning with  "a"  or  "b",  it
+     matches  the  empty string at the start of the subject. With
+     PCRE_NOTEMPTY set, this match is not valid, so PCRE searches
+     further into the string for occurrences of "a" or "b".
+
+     Perl has no direct equivalent of PCRE_NOTEMPTY, but it  does
+     make  a  special case of a pattern match of the empty string
+     within its split() function, and when using the /g modifier.
+     It  is possible to emulate Perl's behaviour after matching a
+     null string by first trying the  match  again  at  the  same
+     offset  with  PCRE_NOTEMPTY  set,  and then if that fails by
+     advancing the starting offset  (see  below)  and  trying  an
+     ordinary match again.
+
+     The subject string is passed as  a  pointer  in  subject,  a
+     length  in  length,  and  a  starting offset in startoffset.
+     Unlike the pattern string, it may contain binary zero  char-
+     acters.  When  the starting offset is zero, the search for a
+     match starts at the beginning of the subject, and this is by
+     far the most common case.
+
+     A non-zero starting offset  is  useful  when  searching  for
+     another  match  in  the  same subject by calling pcre_exec()
+     again after a previous success.  Setting startoffset differs
+     from  just  passing  over  a  shortened  string  and setting
+     PCRE_NOTBOL in the case of a pattern that  begins  with  any
+     kind of lookbehind. For example, consider the pattern
+
+       \Biss\B
+
+     which finds occurrences of "iss" in the middle of words. (\B
+     matches only if the current position in the subject is not a
+     word boundary.) When applied to the string "Mississipi"  the
+     first  call  to  pcre_exec()  finds the first occurrence. If
+     pcre_exec() is called again with just the remainder  of  the
+     subject,  namely  "issipi", it does not match, because \B is
+     always false at the start of the subject, which is deemed to
+     be  a  word  boundary. However, if pcre_exec() is passed the
+     entire string again, but with startoffset set to 4, it finds
+     the  second  occurrence  of "iss" because it is able to look
+     behind the starting point to discover that it is preceded by
+     a letter.
+
+     If a non-zero starting offset is passed when the pattern  is
+     anchored, one attempt to match at the given offset is tried.
+     This can only succeed if the pattern does  not  require  the
+     match to be at the start of the subject.
+
+     In general, a pattern matches a certain portion of the  sub-
+     ject,  and  in addition, further substrings from the subject
+     may be picked out by parts of  the  pattern.  Following  the
+     usage  in  Jeffrey Friedl's book, this is called "capturing"
+     in what follows, and the phrase  "capturing  subpattern"  is
+     used for a fragment of a pattern that picks out a substring.
+     PCRE supports several other kinds of  parenthesized  subpat-
+     tern that do not cause substrings to be captured.
+
+     Captured substrings are returned to the caller via a  vector
+     of  integer  offsets whose address is passed in ovector. The
+     number of elements in the vector is passed in ovecsize.  The
+     first two-thirds of the vector is used to pass back captured
+     substrings, each substring using a  pair  of  integers.  The
+     remaining  third  of  the  vector  is  used  as workspace by
+     pcre_exec() while matching capturing subpatterns, and is not
+     available for passing back information. The length passed in
+     ovecsize should always be a multiple of three. If it is not,
+     it is rounded down.
+
+     When a match has been successful, information about captured
+     substrings is returned in pairs of integers, starting at the
+     beginning of ovector, and continuing up to two-thirds of its
+     length  at  the  most. The first element of a pair is set to
+     the offset of the first character in a  substring,  and  the
+     second is set to the offset of the first character after the
+     end of a substring. The first  pair,  ovector[0]  and  ovec-
+     tor[1],  identify  the portion of the subject string matched
+     by the entire pattern. The next pair is used for  the  first
+     capturing  subpattern,  and  so  on.  The  value returned by
+     pcre_exec() is the number of pairs that have  been  set.  If
+     there  are no capturing subpatterns, the return value from a
+     successful match is 1, indicating that just the  first  pair
+     of offsets has been set.
+
+     Some convenience functions are provided for  extracting  the
+     captured substrings as separate strings. These are described
+     in the following section.
+
+     It is possible for an capturing  subpattern  number  n+1  to
+     match  some  part  of  the subject when subpattern n has not
+     been used at all.  For  example,  if  the  string  "abc"  is
+     matched  against the pattern (a|(z))(bc) subpatterns 1 and 3
+     are matched, but 2 is not. When this  happens,  both  offset
+     values corresponding to the unused subpattern are set to -1.
+
+     If a capturing subpattern is matched repeatedly, it  is  the
+     last  portion  of  the  string  that  it  matched  that gets
+     returned.
+
+     If the vector is too small to hold  all  the  captured  sub-
+     strings,  it is used as far as possible (up to two-thirds of
+     its length), and the function returns a value  of  zero.  In
+     particular,  if  the  substring offsets are not of interest,
+     pcre_exec() may be called with ovector passed  as  NULL  and
+     ovecsize  as  zero.  However,  if  the pattern contains back
+     references and the ovector isn't big enough to remember  the
+     related  substrings,  PCRE  has to get additional memory for
+     use during matching. Thus it is usually advisable to  supply
+     an ovector.
+
+     Note that pcre_info() can be used to find out how many  cap-
+     turing  subpatterns  there  are  in  a compiled pattern. The
+     smallest size for ovector that will  allow  for  n  captured
+     substrings  in  addition  to  the  offsets  of the substring
+     matched by the whole pattern is (n+1)*3.
+
+     If pcre_exec() fails, it returns a negative number. The fol-
+     lowing are defined in the header file:
+
+       PCRE_ERROR_NOMATCH        (-1)
+
+     The subject string did not match the pattern.
+
+       PCRE_ERROR_NULL           (-2)
+
+     Either code or subject was passed as NULL,  or  ovector  was
+     NULL and ovecsize was not zero.
+
+       PCRE_ERROR_BADOPTION      (-3)
+
+     An unrecognized bit was set in the options argument.
+
+       PCRE_ERROR_BADMAGIC       (-4)
+
+     PCRE stores a 4-byte "magic number" at the start of the com-
+     piled  code,  to  catch  the  case  when it is passed a junk
+     pointer. This is the error it gives when  the  magic  number
+     isn't present.
+
+       PCRE_ERROR_UNKNOWN_NODE   (-5)
+
+     While running the pattern match, an unknown item was encoun-
+     tered in the compiled pattern. This error could be caused by
+     a bug in PCRE or by overwriting of the compiled pattern.
+
+       PCRE_ERROR_NOMEMORY       (-6)
+
+     If a pattern contains back references, but the ovector  that
+     is  passed  to pcre_exec() is not big enough to remember the
+     referenced substrings, PCRE gets a block of  memory  at  the
+     start  of  matching to use for this purpose. If the call via
+     pcre_malloc() fails, this error  is  given.  The  memory  is
+     freed at the end of matching.
+
+
+
+EXTRACTING CAPTURED SUBSTRINGS
+     Captured substrings can be accessed directly  by  using  the
+     offsets returned by pcre_exec() in ovector. For convenience,
+     the functions  pcre_copy_substring(),  pcre_get_substring(),
+     and  pcre_get_substring_list()  are  provided for extracting
+     captured  substrings  as  new,   separate,   zero-terminated
+     strings.   A  substring  that  contains  a  binary  zero  is
+     correctly extracted and has a further zero added on the end,
+     but the result does not, of course, function as a C string.
+
+     The first three arguments are the same for all  three  func-
+     tions:  subject  is  the  subject string which has just been
+     successfully matched, ovector is a pointer to the vector  of
+     integer   offsets   that  was  passed  to  pcre_exec(),  and
+     stringcount is the number of substrings that  were  captured
+     by  the  match,  including  the  substring  that matched the
+     entire regular expression. This is  the  value  returned  by
+     pcre_exec  if  it  is  greater  than  zero.  If  pcre_exec()
+     returned zero, indicating that it ran out of space in  ovec-
+     tor, then the value passed as stringcount should be the size
+     of the vector divided by three.
+
+     The functions pcre_copy_substring() and pcre_get_substring()
+     extract a single substring, whose number is given as string-
+     number. A value of zero extracts the substring that  matched
+     the entire pattern, while higher values extract the captured
+     substrings. For pcre_copy_substring(), the string is  placed
+     in  buffer,  whose  length is given by buffersize, while for
+     pcre_get_substring() a new block of store  is  obtained  via
+     pcre_malloc,  and its address is returned via stringptr. The
+     yield of the function is  the  length  of  the  string,  not
+     including the terminating zero, or one of
+
+       PCRE_ERROR_NOMEMORY       (-6)
+
+     The buffer was too small for pcre_copy_substring(),  or  the
+     attempt to get memory failed for pcre_get_substring().
+
+       PCRE_ERROR_NOSUBSTRING    (-7)
+
+     There is no substring whose number is stringnumber.
+
+     The pcre_get_substring_list() function extracts  all  avail-
+     able  substrings  and builds a list of pointers to them. All
+     this is done in a single block of memory which  is  obtained
+     via pcre_malloc. The address of the memory block is returned
+     via listptr, which is also the start of the list  of  string
+     pointers.  The  end of the list is marked by a NULL pointer.
+     The yield of the function is zero if all went well, or
+
+       PCRE_ERROR_NOMEMORY       (-6)
+
+     if the attempt to get the memory block failed.
+
+     When any of these functions encounter a  substring  that  is
+     unset, which can happen when capturing subpattern number n+1
+     matches some part of the subject, but subpattern n  has  not
+     been  used  at all, they return an empty string. This can be
+     distinguished  from  a  genuine  zero-length  substring   by
+     inspecting the appropriate offset in ovector, which is nega-
+     tive for unset substrings.
+
+
+
+
+LIMITATIONS
+     There are some size limitations in PCRE but it is hoped that
+     they will never in practice be relevant.  The maximum length
+     of a compiled pattern is 65539 (sic) bytes.  All  values  in
+     repeating  quantifiers must be less than 65536.  The maximum
+     number of capturing subpatterns is 99.  The  maximum  number
+     of  all  parenthesized subpatterns, including capturing sub-
+     patterns, assertions, and other types of subpattern, is 200.
+
+     The maximum length of a subject string is the largest  posi-
+     tive number that an integer variable can hold. However, PCRE
+     uses recursion to handle subpatterns and indefinite  repeti-
+     tion.  This  means  that the available stack space may limit
+     the size of a subject string that can be processed  by  cer-
+     tain patterns.
+
+
+
+DIFFERENCES FROM PERL
+     The differences described here  are  with  respect  to  Perl
+     5.005.
+
+     1. By default, a whitespace character is any character  that
+     the  C  library  function isspace() recognizes, though it is
+     possible to compile PCRE  with  alternative  character  type
+     tables. Normally isspace() matches space, formfeed, newline,
+     carriage return, horizontal tab, and vertical tab. Perl 5 no
+     longer  includes vertical tab in its set of whitespace char-
+     acters. The \v escape that was in the Perl documentation for
+     a long time was never in fact recognized. However, the char-
+     acter itself was treated as whitespace at least up to 5.002.
+     In 5.004 and 5.005 it does not match \s.
+
+     2. PCRE does  not  allow  repeat  quantifiers  on  lookahead
+     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.
+
+     3. Capturing subpatterns that occur inside  negative  looka-
+     head  assertions  are  counted,  but  their  entries  in the
+     offsets vector are never set. Perl sets its numerical  vari-
+     ables  from  any  such  patterns that are matched before the
+     assertion fails to match something (thereby succeeding), but
+     only  if  the negative lookahead assertion contains just one
+     branch.
+
+     4. Though binary zero characters are supported in  the  sub-
+     ject  string,  they  are  not  allowed  in  a pattern string
+     because it is passed as a normal  C  string,  terminated  by
+     zero. The escape sequence "\0" can be used in the pattern to
+     represent a binary zero.
+
+     5. The following Perl escape sequences  are  not  supported:
+     \l,  \u,  \L,  \U,  \E, \Q. In fact these are implemented by
+     Perl's general string-handling and are not part of its  pat-
+     tern matching engine.
+
+     6. The Perl \G assertion is  not  supported  as  it  is  not
+     relevant to single pattern matches.
+
+     7. Fairly obviously, PCRE does not support the (?{code}) and
+     (?p{code})  constructions. However, there is some experimen-
+     tal support for recursive patterns using the  non-Perl  item
+     (?R).
+     8. There are at the time of writing some  oddities  in  Perl
+     5.005_02  concerned  with  the  settings of captured strings
+     when part of a pattern is repeated.  For  example,  matching
+     "aba"  against the pattern /^(a(b)?)+$/ sets $2 to the value
+     "b", but matching "aabbaa" against /^(aa(bb)?)+$/ leaves  $2
+     unset.    However,    if   the   pattern   is   changed   to
+     /^(aa(b(b))?)+$/ then $2 (and $3) get set.
+
+     In Perl 5.004 $2 is set in both cases, and that is also true
+     of PCRE. If in the future Perl changes to a consistent state
+     that is different, PCRE may change to follow.
+
+     9. Another as yet unresolved discrepancy  is  that  in  Perl
+     5.005_02  the  pattern /^(a)?(?(1)a|b)+$/ matches the string
+     "a", whereas in PCRE it does not.  However, in both Perl and
+     PCRE /^(a)?a/ matched against "a" leaves $1 unset.
+
+     10. PCRE  provides  some  extensions  to  the  Perl  regular
+     expression facilities:
+
+     (a) Although lookbehind assertions must match  fixed  length
+     strings,  each  alternative branch of a lookbehind assertion
+     can match a different length of string. Perl 5.005  requires
+     them all to have the same length.
+
+     (b) If PCRE_DOLLAR_ENDONLY is set and PCRE_MULTILINE is  not
+     set,  the  $ meta- character matches only at the very end of
+     the string.
+
+     (c) If PCRE_EXTRA is set, a backslash followed by  a  letter
+     with no special meaning is faulted.
+
+     (d) If PCRE_UNGREEDY is set, the greediness of  the  repeti-
+     tion  quantifiers  is inverted, that is, by default they are
+     not greedy, but if followed by a question mark they are.
+
+     (e) PCRE_ANCHORED can be used to force a pattern to be tried
+     only at the start of the subject.
+
+     (f) The PCRE_NOTBOL, PCRE_NOTEOL, and PCRE_NOTEMPTY  options
+     for pcre_exec() have no Perl equivalents.
+
+     (g) The (?R) construct allows for recursive pattern matching
+     (Perl  5.6 can do this using the (?p{code}) construct, which
+     PCRE cannot of course support.)
+
+
+
+REGULAR EXPRESSION DETAILS
+     The syntax and semantics of  the  regular  expressions  sup-
+     ported  by PCRE are described below. Regular expressions are
+     also described in the Perl documentation and in a number  of
+
+     other  books,  some  of which have copious examples. Jeffrey
+     Friedl's  "Mastering  Regular  Expressions",  published   by
+     O'Reilly  (ISBN  1-56592-257),  covers them in great detail.
+     The description here is intended as reference documentation.
+
+     A regular expression is a pattern that is matched against  a
+     subject string from left to right. Most characters stand for
+     themselves in a pattern, and match the corresponding charac-
+     ters in the subject. As a trivial example, the pattern
+
+       The quick brown fox
+
+     matches a portion of a subject string that is  identical  to
+     itself.  The  power  of  regular  expressions comes from the
+     ability to include alternatives and repetitions in the  pat-
+     tern.  These  are encoded in the pattern by the use of meta-
+     characters, which do not stand for  themselves  but  instead
+     are interpreted in some special way.
+
+     There are two different sets of meta-characters: those  that
+     are  recognized anywhere in the pattern except within square
+     brackets, and those that are recognized in square  brackets.
+     Outside square brackets, the meta-characters are as follows:
+
+       \      general escape character with several uses
+       ^      assert start of  subject  (or  line,  in  multiline
+     mode)
+       $      assert end of subject (or line, in multiline mode)
+       .      match any character except newline (by default)
+       [      start character class definition
+       |      start of alternative branch
+       (      start subpattern
+       )      end subpattern
+       ?      extends the meaning of (
+              also 0 or 1 quantifier
+              also quantifier minimizer
+       *      0 or more quantifier
+       +      1 or more quantifier
+       {      start min/max quantifier
+
+     Part of a pattern that is in square  brackets  is  called  a
+     "character  class".  In  a  character  class  the only meta-
+     characters are:
+
+       \      general escape character
+       ^      negate the class, but only if the first character
+       -      indicates character range
+       ]      terminates the character class
+
+     The following sections describe  the  use  of  each  of  the
+     meta-characters.
+
+
+
+BACKSLASH
+     The backslash character has several uses. Firstly, if it  is
+     followed  by  a  non-alphameric character, it takes away any
+     special  meaning  that  character  may  have.  This  use  of
+     backslash  as  an  escape  character applies both inside and
+     outside character classes.
+
+     For example, if you want to match a "*" character, you write
+     "\*" in the pattern. This applies whether or not the follow-
+     ing character would otherwise  be  interpreted  as  a  meta-
+     character,  so it is always safe to precede a non-alphameric
+     with "\" to specify that it stands for itself.  In  particu-
+     lar, if you want to match a backslash, you write "\\".
+
+     If a pattern is compiled with the PCRE_EXTENDED option, whi-
+     tespace in the pattern (other than in a character class) and
+     characters between a "#" outside a character class  and  the
+     next  newline  character  are ignored. An escaping backslash
+     can be used to include a whitespace or "#" character as part
+     of the pattern.
+
+     A second use of backslash provides a way  of  encoding  non-
+     printing  characters  in patterns in a visible manner. There
+     is no restriction on the appearance of non-printing  charac-
+     ters,  apart from the binary zero that terminates a pattern,
+     but when a pattern is being prepared by text editing, it  is
+     usually  easier to use one of the following escape sequences
+     than the binary character it represents:
+
+       \a     alarm, that is, the BEL character (hex 07)
+       \cx    "control-x", where x is any character
+       \e     escape (hex 1B)
+       \f     formfeed (hex 0C)
+       \n     newline (hex 0A)
+       \r     carriage return (hex 0D)
+       \t     tab (hex 09)
+       \xhh   character with hex code hh
+       \ddd   character with octal code ddd, or backreference
+
+     The precise effect of "\cx" is as follows: if "x" is a lower
+     case  letter,  it  is converted to upper case. Then bit 6 of
+     the character (hex 40) is inverted.  Thus "\cz" becomes  hex
+     1A, but "\c{" becomes hex 3B, while "\c;" becomes hex 7B.
+
+     After "\x", up to two hexadecimal digits are  read  (letters
+     can be in upper or lower case).
+
+     After "\0" up to two further octal digits are read. In  both
+     cases,  if  there are fewer than two digits, just those that
+     are present are used. Thus the sequence "\0\x\07"  specifies
+     two binary zeros followed by a BEL character.  Make sure you
+     supply two digits after the initial zero  if  the  character
+     that follows is itself an octal digit.
+
+     The handling of a backslash followed by a digit other than 0
+     is  complicated.   Outside  a character class, PCRE reads it
+     and any following digits as a decimal number. If the  number
+     is  less  than  10, or if there have been at least that many
+     previous capturing left parentheses in the  expression,  the
+     entire  sequence is taken as a back reference. A description
+     of how this works is given later, following  the  discussion
+     of parenthesized subpatterns.
+
+     Inside a character  class,  or  if  the  decimal  number  is
+     greater  than  9 and there have not been that many capturing
+     subpatterns, PCRE re-reads up to three octal digits  follow-
+     ing  the  backslash,  and  generates  a single byte from the
+     least significant 8 bits of the value. Any subsequent digits
+     stand for themselves.  For example:
+
+       \040   is another way of writing a space
+       \40    is the same, provided there are fewer than 40
+                 previous capturing subpatterns
+       \7     is always a back reference
+       \11    might be a back reference, or another way of
+                 writing a tab
+       \011   is always a tab
+       \0113  is a tab followed by the character "3"
+       \113   is the character with octal code 113 (since there
+                 can be no more than 99 back references)
+       \377   is a byte consisting entirely of 1 bits
+       \81    is either a back reference, or a binary zero
+                 followed by the two characters "8" and "1"
+
+     Note that octal values of 100 or greater must not be  intro-
+     duced  by  a  leading zero, because no more than three octal
+     digits are ever read.
+
+     All the sequences that define a single  byte  value  can  be
+     used both inside and outside character classes. In addition,
+     inside a character class, the sequence "\b"  is  interpreted
+     as  the  backspace  character  (hex 08). Outside a character
+     class it has a different meaning (see below).
+
+     The third use of backslash is for specifying generic charac-
+     ter types:
+
+       \d     any decimal digit
+       \D     any character that is not a decimal digit
+       \s     any whitespace character
+       \S     any character that is not a whitespace character
+       \w     any "word" character
+       \W     any "non-word" character
+
+     Each pair of escape sequences partitions the complete set of
+     characters  into  two  disjoint  sets.  Any  given character
+     matches one, and only one, of each pair.
+
+     A "word" character is any letter or digit or the  underscore
+     character,  that  is,  any  character which can be part of a
+     Perl "word". The definition of letters and  digits  is  con-
+     trolled  by PCRE's character tables, and may vary if locale-
+     specific matching is  taking  place  (see  "Locale  support"
+     above). For example, in the "fr" (French) locale, some char-
+     acter codes greater than 128 are used for accented  letters,
+     and these are matched by \w.
+
+     These character type sequences can appear  both  inside  and
+     outside  character classes. They each match one character of
+     the appropriate type. If the current matching  point  is  at
+     the end of the subject string, all of them fail, since there
+     is no character to match.
+
+     The fourth use of backslash is  for  certain  simple  asser-
+     tions. An assertion specifies a condition that has to be met
+     at a particular point in  a  match,  without  consuming  any
+     characters  from  the subject string. The use of subpatterns
+     for more complicated  assertions  is  described  below.  The
+     backslashed assertions are
+
+       \b     word boundary
+       \B     not a word boundary
+       \A     start of subject (independent of multiline mode)
+       \Z     end of subject or newline at  end  (independent  of
+     multiline mode)
+       \z     end of subject (independent of multiline mode)
+
+     These assertions may not appear in  character  classes  (but
+     note that "\b" has a different meaning, namely the backspace
+     character, inside a character class).
+
+     A word boundary is a position in the  subject  string  where
+     the current character and the previous character do not both
+     match \w or \W (i.e. one matches \w and  the  other  matches
+     \W),  or the start or end of the string if the first or last
+     character matches \w, respectively.
+
+     The \A, \Z, and \z assertions differ  from  the  traditional
+     circumflex  and  dollar  (described below) in that they only
+     ever match at the very start and end of the subject  string,
+     whatever  options  are  set.  They  are  not affected by the
+     PCRE_NOTBOL or PCRE_NOTEOL options. If the startoffset argu-
+     ment  of  pcre_exec()  is  non-zero, \A can never match. The
+     difference between \Z and \z is that  \Z  matches  before  a
+     newline  that is the last character of the string as well as
+     at the end of the string, whereas \z  matches  only  at  the
+     end.
+
+
+
+CIRCUMFLEX AND DOLLAR
+     Outside a character class, in the default matching mode, the
+     circumflex  character  is an assertion which is true only if
+     the current matching point is at the start  of  the  subject
+     string.  If  the startoffset argument of pcre_exec() is non-
+     zero, circumflex can never match. Inside a character  class,
+     circumflex has an entirely different meaning (see below).
+
+     Circumflex need not be the first character of the pattern if
+     a  number of alternatives are involved, but it should be the
+     first thing in each alternative in which it appears  if  the
+     pattern is ever to match that branch. If all possible alter-
+     natives start with a circumflex, that is, if the pattern  is
+     constrained to match only at the start of the subject, it is
+     said to be an "anchored" pattern. (There are also other con-
+     structs that can cause a pattern to be anchored.)
+
+     A dollar character is an assertion which is true only if the
+     current  matching point is at the end of the subject string,
+     or immediately before a newline character that is  the  last
+     character in the string (by default). Dollar need not be the
+     last character of the pattern if a  number  of  alternatives
+     are  involved,  but it should be the last item in any branch
+     in which it appears.  Dollar has no  special  meaning  in  a
+     character class.
+
+     The meaning of dollar can be changed so that it matches only
+     at   the   very   end   of   the   string,  by  setting  the
+     PCRE_DOLLAR_ENDONLY option at compile or matching time. This
+     does not affect the \Z assertion.
+
+     The meanings of the circumflex  and  dollar  characters  are
+     changed  if  the  PCRE_MULTILINE option is set. When this is
+     the case,  they  match  immediately  after  and  immediately
+     before an internal "\n" character, respectively, in addition
+     to matching at the start and end of the subject string.  For
+     example,  the  pattern  /^abc$/  matches  the subject string
+     "def\nabc" in multiline  mode,  but  not  otherwise.  Conse-
+     quently,  patterns  that  are  anchored  in single line mode
+     because all branches start with "^" are not anchored in mul-
+     tiline mode, and a match for circumflex is possible when the
+     startoffset  argument  of  pcre_exec()  is   non-zero.   The
+     PCRE_DOLLAR_ENDONLY  option  is ignored if PCRE_MULTILINE is
+     set.
+
+     Note that the sequences \A, \Z, and \z can be used to  match
+     the  start  and end of the subject in both modes, and if all
+     branches of a pattern start with \A is it  always  anchored,
+     whether PCRE_MULTILINE is set or not.
+
+
+
+FULL STOP (PERIOD, DOT)
+     Outside a character class, a dot in the pattern matches  any
+     one character in the subject, including a non-printing char-
+     acter, but not (by default)  newline.   If  the  PCRE_DOTALL
+     option  is  set,  then dots match newlines as well. The han-
+     dling of dot is entirely independent of the handling of cir-
+     cumflex  and  dollar,  the only relationship being that they
+     both involve newline characters.  Dot has no special meaning
+     in a character class.
+
+
+
+SQUARE BRACKETS
+     An opening square bracket introduces a character class, ter-
+     minated  by  a  closing  square  bracket.  A  closing square
+     bracket on its own is  not  special.  If  a  closing  square
+     bracket  is  required as a member of the class, it should be
+     the first data character in the class (after an initial cir-
+     cumflex, if present) or escaped with a backslash.
+
+     A character class matches a single character in the subject;
+     the  character  must  be in the set of characters defined by
+     the class, unless the first character in the class is a cir-
+     cumflex,  in which case the subject character must not be in
+     the set defined by the class. If a  circumflex  is  actually
+     required  as  a  member  of  the class, ensure it is not the
+     first character, or escape it with a backslash.
+
+     For example, the character class [aeiou] matches  any  lower
+     case vowel, while [^aeiou] matches any character that is not
+     a lower case vowel. Note that a circumflex is  just  a  con-
+     venient  notation for specifying the characters which are in
+     the class by enumerating those that are not. It  is  not  an
+     assertion:  it  still  consumes a character from the subject
+     string, and fails if the current pointer is at  the  end  of
+     the string.
+
+     When caseless matching  is  set,  any  letters  in  a  class
+     represent  both their upper case and lower case versions, so
+     for example, a caseless [aeiou] matches "A" as well as  "a",
+     and  a caseless [^aeiou] does not match "A", whereas a case-
+     ful version would.
+
+     The newline character is never treated in any special way in
+     character  classes,  whatever the setting of the PCRE_DOTALL
+     or PCRE_MULTILINE options is. A  class  such  as  [^a]  will
+     always match a newline.
+
+     The minus (hyphen) character can be used to specify a  range
+     of  characters  in  a  character  class.  For example, [d-m]
+     matches any letter between d and m, inclusive.  If  a  minus
+     character  is required in a class, it must be escaped with a
+     backslash or appear in a position where it cannot be  inter-
+     preted as indicating a range, typically as the first or last
+     character in the class.
+
+     It is not possible to have the literal character "]" as  the
+     end  character  of  a  range.  A  pattern such as [W-]46] is
+     interpreted as a class of two characters ("W" and "-")  fol-
+     lowed by a literal string "46]", so it would match "W46]" or
+     "-46]". However, if the "]" is escaped with a  backslash  it
+     is  interpreted  as  the end of range, so [W-\]46] is inter-
+     preted as a single class containing a range followed by  two
+     separate characters. The octal or hexadecimal representation
+     of "]" can also be used to end a range.
+
+     Ranges operate in ASCII collating sequence. They can also be
+     used  for  characters  specified  numerically,  for  example
+     [\000-\037]. If a range that includes letters is  used  when
+     caseless  matching  is set, it matches the letters in either
+     case. For example, [W-c] is equivalent  to  [][\^_`wxyzabc],
+     matched  caselessly,  and  if  character tables for the "fr"
+     locale are in use, [\xc8-\xcb] matches accented E characters
+     in both cases.
+
+     The character types \d, \D, \s, \S,  \w,  and  \W  may  also
+     appear  in  a  character  class, and add the characters that
+     they match to the class. For example, [\dABCDEF] matches any
+     hexadecimal  digit.  A  circumflex  can conveniently be used
+     with the upper case character types to specify a  more  res-
+     tricted set of characters than the matching lower case type.
+     For example, the class [^\W_] matches any letter  or  digit,
+     but not underscore.
+
+     All non-alphameric characters other than \,  -,  ^  (at  the
+     start)  and  the  terminating ] are non-special in character
+     classes, but it does no harm if they are escaped.
+
+
+
+POSIX CHARACTER CLASSES
+     Perl 5.6 (not yet released at the time of writing) is  going
+     to  support  the POSIX notation for character classes, which
+     uses names enclosed by  [:  and  :]   within  the  enclosing
+     square brackets. PCRE supports this notation. For example,
+
+       [01[:alpha:]%]
+
+     matches "0", "1", any alphabetic character, or "%". The sup-
+     ported class names are
+
+       alnum    letters and digits
+       alpha    letters
+       ascii    character codes 0 - 127
+       cntrl    control characters
+       digit    decimal digits (same as \d)
+       graph    printing characters, excluding space
+       lower    lower case letters
+       print    printing characters, including space
+       punct    printing characters, excluding letters and digits
+       space    white space (same as \s)
+       upper    upper case letters
+       word     "word" characters (same as \w)
+       xdigit   hexadecimal digits
+
+     The names "ascii" and "word" are  Perl  extensions.  Another
+     Perl  extension is negation, which is indicated by a ^ char-
+     acter after the colon. For example,
+
+       [12[:^digit:]]
+
+     matches "1", "2", or any non-digit.  PCRE  (and  Perl)  also
+     recogize  the POSIX syntax [.ch.] and [=ch=] where "ch" is a
+     "collating element", but these are  not  supported,  and  an
+     error is given if they are encountered.
+
+
+
+VERTICAL BAR
+     Vertical bar characters are  used  to  separate  alternative
+     patterns. For example, the pattern
+
+       gilbert|sullivan
+
+     matches either "gilbert" or "sullivan". Any number of alter-
+     natives  may  appear,  and an empty alternative is permitted
+     (matching the empty string).   The  matching  process  tries
+     each  alternative in turn, from left to right, and the first
+     one that succeeds is used. If the alternatives are within  a
+     subpattern  (defined  below),  "succeeds" means matching the
+     rest of the main pattern as well as the alternative  in  the
+     subpattern.
+
+
+
+INTERNAL OPTION SETTING
+     The settings of PCRE_CASELESS, PCRE_MULTILINE,  PCRE_DOTALL,
+     and  PCRE_EXTENDED can be changed from within the pattern by
+     a sequence of Perl option letters enclosed between "(?"  and
+     ")". The option letters are
+
+       i  for PCRE_CASELESS
+       m  for PCRE_MULTILINE
+       s  for PCRE_DOTALL
+       x  for PCRE_EXTENDED
+
+     For example, (?im) sets caseless, multiline matching. It  is
+     also possible to unset these options by preceding the letter
+     with a hyphen, and a combined setting and unsetting such  as
+     (?im-sx),  which sets PCRE_CASELESS and PCRE_MULTILINE while
+     unsetting PCRE_DOTALL and PCRE_EXTENDED, is also  permitted.
+     If  a  letter  appears both before and after the hyphen, the
+     option is unset.
+
+     The scope of these option changes depends on  where  in  the
+     pattern  the  setting  occurs. For settings that are outside
+     any subpattern (defined below), the effect is the same as if
+     the  options were set or unset at the start of matching. The
+     following patterns all behave in exactly the same way:
+
+       (?i)abc
+       a(?i)bc
+       ab(?i)c
+       abc(?i)
+
+     which in turn is the same as compiling the pattern abc  with
+     PCRE_CASELESS  set.   In  other words, such "top level" set-
+     tings apply to the whole pattern  (unless  there  are  other
+     changes  inside subpatterns). If there is more than one set-
+     ting of the same option at top level, the rightmost  setting
+     is used.
+
+     If an option change occurs inside a subpattern,  the  effect
+     is  different.  This is a change of behaviour in Perl 5.005.
+     An option change inside a subpattern affects only that  part
+     of the subpattern that follows it, so
+
+       (a(?i)b)c
+
+     matches  abc  and  aBc  and  no  other   strings   (assuming
+     PCRE_CASELESS  is  not used).  By this means, options can be
+     made to have different settings in different  parts  of  the
+     pattern.  Any  changes  made  in one alternative do carry on
+     into subsequent branches within  the  same  subpattern.  For
+     example,
+
+       (a(?i)b|c)
+
+     matches "ab", "aB", "c", and "C", even though when  matching
+     "C" the first branch is abandoned before the option setting.
+     This is because the effects of  option  settings  happen  at
+     compile  time. There would be some very weird behaviour oth-
+     erwise.
+
+     The PCRE-specific options PCRE_UNGREEDY and  PCRE_EXTRA  can
+     be changed in the same way as the Perl-compatible options by
+     using the characters U and X  respectively.  The  (?X)  flag
+     setting  is  special in that it must always occur earlier in
+     the pattern than any of the additional features it turns on,
+     even when it is at top level. It is best put at the start.
+
+
+
+SUBPATTERNS
+     Subpatterns are delimited by parentheses  (round  brackets),
+     which can be nested.  Marking part of a pattern as a subpat-
+     tern does two things:
+
+     1. It localizes a set of alternatives. For example, the pat-
+     tern
+
+       cat(aract|erpillar|)
+
+     matches one of the words "cat",  "cataract",  or  "caterpil-
+     lar".  Without  the  parentheses, it would match "cataract",
+     "erpillar" or the empty string.
+
+     2. It sets up the subpattern as a capturing  subpattern  (as
+     defined  above).   When the whole pattern matches, that por-
+     tion of the subject string that matched  the  subpattern  is
+     passed  back  to  the  caller  via  the  ovector argument of
+     pcre_exec(). Opening parentheses are counted  from  left  to
+     right (starting from 1) to obtain the numbers of the captur-
+     ing subpatterns.
+
+     For example, if the string "the red king" is matched against
+     the pattern
+
+       the ((red|white) (king|queen))
+
+     the captured substrings are "red king", "red",  and  "king",
+     and are numbered 1, 2, and 3.
+
+     The fact that plain parentheses fulfil two functions is  not
+     always  helpful.  There are often times when a grouping sub-
+     pattern is required without a capturing requirement.  If  an
+     opening parenthesis is followed by "?:", the subpattern does
+     not do any capturing, and is not counted when computing  the
+     number of any subsequent capturing subpatterns. For example,
+     if the string "the white queen" is matched against the  pat-
+     tern
+
+       the ((?:red|white) (king|queen))
+
+     the captured substrings are "white queen" and  "queen",  and
+     are  numbered  1  and 2. The maximum number of captured sub-
+     strings is 99, and the maximum number  of  all  subpatterns,
+     both capturing and non-capturing, is 200.
+
+     As a  convenient  shorthand,  if  any  option  settings  are
+     required  at  the  start  of a non-capturing subpattern, the
+     option letters may appear between the "?" and the ":".  Thus
+     the two patterns
+
+       (?i:saturday|sunday)
+       (?:(?i)saturday|sunday)
+
+     match exactly the same set of strings.  Because  alternative
+     branches  are  tried from left to right, and options are not
+     reset until the end of the subpattern is reached, an  option
+     setting  in  one  branch does affect subsequent branches, so
+     the above patterns match "SUNDAY" as well as "Saturday".
+
+
+
+REPETITION
+     Repetition is specified by quantifiers, which can follow any
+     of the following items:
+
+       a single character, possibly escaped
+       the . metacharacter
+       a character class
+       a back reference (see next section)
+       a parenthesized subpattern (unless it is  an  assertion  -
+     see below)
+
+     The general repetition quantifier specifies  a  minimum  and
+     maximum  number  of  permitted  matches,  by  giving the two
+     numbers in curly brackets (braces), separated  by  a  comma.
+     The  numbers  must be less than 65536, and the first must be
+     less than or equal to the second. For example:
+
+       z{2,4}
+
+     matches "zz", "zzz", or "zzzz". A closing brace on  its  own
+     is not a special character. If the second number is omitted,
+     but the comma is present, there is no upper  limit;  if  the
+     second number and the comma are both omitted, the quantifier
+     specifies an exact number of required matches. Thus
+
+       [aeiou]{3,}
+
+     matches at least 3 successive vowels,  but  may  match  many
+     more, while
+
+       \d{8}
+
+     matches exactly 8 digits.  An  opening  curly  bracket  that
+     appears  in a position where a quantifier is not allowed, or
+     one that does not match the syntax of a quantifier, is taken
+     as  a literal character. For example, {,6} is not a quantif-
+     ier, but a literal string of four characters.
+
+     The quantifier {0} is permitted, causing the  expression  to
+     behave  as  if the previous item and the quantifier were not
+     present.
+
+     For convenience (and  historical  compatibility)  the  three
+     most common quantifiers have single-character abbreviations:
+
+       *    is equivalent to {0,}
+       +    is equivalent to {1,}
+       ?    is equivalent to {0,1}
+
+     It is possible to construct infinite loops  by  following  a
+     subpattern  that  can  match no characters with a quantifier
+     that has no upper limit, for example:
+
+       (a?)*
+
+     Earlier versions of Perl and PCRE used to give an  error  at
+     compile  time  for such patterns. However, because there are
+     cases where this  can  be  useful,  such  patterns  are  now
+     accepted,  but  if  any repetition of the subpattern does in
+     fact match no characters, the loop is forcibly broken.
+
+     By default, the quantifiers  are  "greedy",  that  is,  they
+     match  as much as possible (up to the maximum number of per-
+     mitted times), without causing the rest of  the  pattern  to
+     fail. The classic example of where this gives problems is in
+     trying to match comments in C programs. These appear between
+     the  sequences /* and */ and within the sequence, individual
+     * and / characters may appear. An attempt to  match  C  com-
+     ments by applying the pattern
+
+       /\*.*\*/
+
+     to the string
+
+       /* first command */  not comment  /* second comment */
+
+     fails, because it matches  the  entire  string  due  to  the
+     greediness of the .*  item.
+
+     However, if a quantifier is followed  by  a  question  mark,
+     then it ceases to be greedy, and instead matches the minimum
+     number of times possible, so the pattern
+
+       /\*.*?\*/
+
+     does the right thing with the C comments. The meaning of the
+     various  quantifiers is not otherwise changed, just the pre-
+     ferred number of matches.  Do not confuse this use of  ques-
+     tion  mark  with  its  use as a quantifier in its own right.
+     Because it has two uses, it can sometimes appear doubled, as
+     in
+
+       \d??\d
+
+     which matches one digit by preference, but can match two  if
+     that is the only way the rest of the pattern matches.
+
+     If the PCRE_UNGREEDY option is set (an option which  is  not
+     available  in  Perl)  then the quantifiers are not greedy by
+     default, but individual ones can be made greedy by following
+     them  with  a  question mark. In other words, it inverts the
+     default behaviour.
+
+     When a parenthesized subpattern is quantified with a minimum
+     repeat  count  that is greater than 1 or with a limited max-
+     imum, more store is required for the  compiled  pattern,  in
+     proportion to the size of the minimum or maximum.
+
+     If a pattern starts with .* or  .{0,}  and  the  PCRE_DOTALL
+     option (equivalent to Perl's /s) is set, thus allowing the .
+     to match newlines, then the pattern is implicitly  anchored,
+     because whatever follows will be tried against every charac-
+     ter position in the subject string, so there is no point  in
+     retrying  the overall match at any position after the first.
+     PCRE treats such a pattern as though it were preceded by \A.
+     In  cases where it is known that the subject string contains
+     no newlines, it is worth setting PCRE_DOTALL when  the  pat-
+     tern begins with .* in order to obtain this optimization, or
+     alternatively using ^ to indicate anchoring explicitly.
+
+     When a capturing subpattern is repeated, the value  captured
+     is the substring that matched the final iteration. For exam-
+     ple, after
+
+       (tweedle[dume]{3}\s*)+
+
+     has matched "tweedledum tweedledee" the value  of  the  cap-
+     tured  substring  is  "tweedledee".  However,  if  there are
+     nested capturing  subpatterns,  the  corresponding  captured
+     values  may  have been set in previous iterations. For exam-
+     ple, after
+
+       /(a|(b))+/
+
+     matches "aba" the value of the second captured substring  is
+     "b".
+
+
+
+BACK REFERENCES
+     Outside a character class, a backslash followed by  a  digit
+     greater  than  0  (and  possibly  further  digits) is a back
+     reference to a capturing subpattern  earlier  (i.e.  to  its
+     left)  in  the  pattern,  provided there have been that many
+     previous capturing left parentheses.
+
+     However, if the decimal number following  the  backslash  is
+     less  than  10,  it is always taken as a back reference, and
+     causes an error only if there are not  that  many  capturing
+     left  parentheses in the entire pattern. In other words, the
+     parentheses that are referenced need not be to the  left  of
+     the  reference  for  numbers  less  than 10. See the section
+     entitled "Backslash" above for further details of  the  han-
+     dling of digits following a backslash.
+
+     A back reference matches whatever actually matched the  cap-
+     turing subpattern in the current subject string, rather than
+     anything matching the subpattern itself. So the pattern
+
+       (sens|respons)e and \1ibility
+
+     matches "sense and sensibility" and "response and  responsi-
+     bility",  but  not  "sense  and  responsibility". If caseful
+     matching is in force at the time of the back reference, then
+     the case of letters is relevant. For example,
+
+       ((?i)rah)\s+\1
+
+     matches "rah rah" and "RAH RAH", but  not  "RAH  rah",  even
+     though  the  original  capturing subpattern is matched case-
+     lessly.
+
+     There may be more than one back reference to the  same  sub-
+     pattern.  If  a  subpattern  has not actually been used in a
+     particular match, then any  back  references  to  it  always
+     fail. For example, the pattern
+
+       (a|(bc))\2
+
+     always fails if it starts to match  "a"  rather  than  "bc".
+     Because  there  may  be up to 99 back references, all digits
+     following the backslash are taken as  part  of  a  potential
+     back reference number. If the pattern continues with a digit
+     character, then some delimiter must be used to terminate the
+     back reference. If the PCRE_EXTENDED option is set, this can
+     be whitespace.  Otherwise an empty comment can be used.
+
+     A back reference that occurs inside the parentheses to which
+     it  refers  fails when the subpattern is first used, so, for
+     example, (a\1) never matches.  However, such references  can
+     be  useful  inside  repeated  subpatterns.  For example, the
+     pattern
+
+       (a|b\1)+
+
+     matches any number of "a"s and also "aba", "ababaa" etc.  At
+     each iteration of the subpattern, the back reference matches
+     the character string corresponding to  the  previous  itera-
+     tion.  In  order  for this to work, the pattern must be such
+     that the first iteration does not need  to  match  the  back
+     reference.  This  can  be  done using alternation, as in the
+     example above, or by a quantifier with a minimum of zero.
+
+
+
+ASSERTIONS
+     An assertion is  a  test  on  the  characters  following  or
+     preceding  the current matching point that does not actually
+     consume any characters. The simple assertions coded  as  \b,
+     \B,  \A,  \Z,  \z, ^ and $ are described above. More compli-
+     cated assertions are coded as  subpatterns.  There  are  two
+     kinds:  those that look ahead of the current position in the
+     subject string, and those 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. Lookahead assertions start with  (?=  for  positive
+     assertions and (?! for negative assertions. For example,
+
+       \w+(?=;)
+
+     matches a word followed by a semicolon, but does not include
+     the semicolon in the match, and
+
+       foo(?!bar)
+
+     matches any occurrence of "foo"  that  is  not  followed  by
+     "bar". Note that the apparently similar pattern
+
+       (?!foo)bar
+
+     does not find an occurrence of "bar"  that  is  preceded  by
+     something other than "foo"; it finds any occurrence of "bar"
+     whatsoever, because the assertion  (?!foo)  is  always  true
+     when  the  next  three  characters  are  "bar". A lookbehind
+     assertion is needed to achieve this effect.
+
+     Lookbehind assertions start with (?<=  for  positive  asser-
+     tions and (?<! for negative assertions. For example,
+
+       (?<!foo)bar
+
+     does find an occurrence of "bar" that  is  not  preceded  by
+     "foo". The contents of a lookbehind assertion are restricted
+     such that all the strings  it  matches  must  have  a  fixed
+     length.  However, if there are several alternatives, they do
+     not all have to have the same fixed length. Thus
+
+       (?<=bullock|donkey)
+
+     is permitted, but
+
+       (?<!dogs?|cats?)
+
+     causes an error at compile time. Branches  that  match  dif-
+     ferent length strings are permitted only at the top level of
+     a lookbehind assertion. This is an extension  compared  with
+     Perl  5.005,  which  requires all branches to match the same
+     length of string. An assertion such as
+
+       (?<=ab(c|de))
+
+     is not permitted, because its single  top-level  branch  can
+     match two different lengths, but it is acceptable if rewrit-
+     ten to use two top-level branches:
+
+       (?<=abc|abde)
+
+     The implementation of lookbehind  assertions  is,  for  each
+     alternative,  to  temporarily move the current position back
+     by the fixed width and then  try  to  match.  If  there  are
+     insufficient  characters  before  the  current position, the
+     match is deemed to fail.  Lookbehinds  in  conjunction  with
+     once-only  subpatterns can be particularly useful for match-
+     ing at the ends of strings; an example is given at  the  end
+     of the section on once-only subpatterns.
+
+     Several assertions (of any sort) may  occur  in  succession.
+     For example,
+
+       (?<=\d{3})(?<!999)foo
+
+     matches "foo" preceded by three digits that are  not  "999".
+     Notice  that each of the assertions is applied independently
+     at the same point in the subject string. First  there  is  a
+     check  that  the  previous  three characters are all digits,
+     then there is a check that the same three characters are not
+     "999".   This  pattern  does not match "foo" preceded by six
+     characters, the first of which are digits and the last three
+     of  which  are  not  "999".  For  example,  it doesn't match
+     "123abcfoo". A pattern to do that is
+
+       (?<=\d{3}...)(?<!999)foo
+
+     This time the first assertion looks  at  the  preceding  six
+     characters,  checking  that  the first three are digits, and
+     then the second assertion checks that  the  preceding  three
+     characters are not "999".
+
+     Assertions can be nested in any combination. For example,
+
+       (?<=(?<!foo)bar)baz
+
+     matches an occurrence of "baz" that  is  preceded  by  "bar"
+     which in turn is not preceded by "foo", while
+
+       (?<=\d{3}(?!999)...)foo
+
+     is another pattern which matches  "foo"  preceded  by  three
+     digits and any three characters that are not "999".
+
+     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.
+
+     Assertions count towards the maximum  of  200  parenthesized
+     subpatterns.
+
+
+
+ONCE-ONLY SUBPATTERNS
+     With both maximizing and minimizing repetition,  failure  of
+     what  follows  normally  causes  the repeated item to be re-
+     evaluated to see if a different number of repeats allows the
+     rest  of  the  pattern  to  match. Sometimes it is useful to
+     prevent this, either to change the nature of the  match,  or
+     to  cause  it fail earlier than it otherwise might, when the
+     author of the pattern knows there is no  point  in  carrying
+     on.
+
+     Consider, for example, the pattern \d+foo  when  applied  to
+     the subject line
+
+       123456bar
+
+     After matching all 6 digits and then failing to match "foo",
+     the normal action of the matcher is to try again with only 5
+     digits matching the \d+ item, and then with 4,  and  so  on,
+     before ultimately failing. Once-only subpatterns provide the
+     means for specifying that once a portion of the pattern  has
+     matched,  it  is  not to be re-evaluated in this way, so the
+     matcher would give up immediately on failing to match  "foo"
+     the  first  time.  The  notation  is another kind of special
+     parenthesis, starting with (?> as in this example:
+
+       (?>\d+)bar
+
+     This kind of parenthesis "locks up" the  part of the pattern
+     it  contains once it has matched, and a failure further into
+     the pattern is prevented from backtracking  into  it.  Back-
+     tracking  past  it to previous items, however, works as nor-
+     mal.
+
+     An alternative description is that a subpattern of this type
+     matches  the  string  of  characters that an identical stan-
+     dalone pattern would match, if anchored at the current point
+     in the subject string.
+
+     Once-only subpatterns are not capturing subpatterns.  Simple
+     cases  such as the above example can be thought of as a max-
+     imizing repeat that must  swallow  everything  it  can.  So,
+     while both \d+ and \d+? are prepared to adjust the number of
+     digits they match in order to make the rest of  the  pattern
+     match, (?>\d+) can only match an entire sequence of digits.
+
+     This construction can of course contain arbitrarily  compli-
+     cated subpatterns, and it can be nested.
+
+     Once-only subpatterns can be used in conjunction with  look-
+     behind  assertions  to specify efficient matching at the end
+     of the subject string. Consider a simple pattern such as
+
+       abcd$
+
+     when applied to a long string which does not match.  Because
+     matching  proceeds  from  left  to right, PCRE will look for
+     each "a" in the subject and then see if what follows matches
+     the rest of the pattern. If the pattern is specified as
+
+       ^.*abcd$
+
+     then the initial .* matches the entire string at first,  but
+     when  this  fails  (because  there  is no following "a"), it
+     backtracks to match all but the last character, then all but
+     the  last  two  characters, and so on. Once again the search
+     for "a" covers the entire string, from right to left, so  we
+     are no better off. However, if the pattern is written as
+
+       ^(?>.*)(?<=abcd)
+
+     then there can be no backtracking for the .*  item;  it  can
+     match  only  the  entire  string.  The subsequent lookbehind
+     assertion does a single test on the last four characters. If
+     it  fails,  the  match  fails immediately. For long strings,
+     this approach makes a significant difference to the process-
+     ing time.
+
+     When a pattern contains an unlimited repeat inside a subpat-
+     tern  that  can  itself  be  repeated an unlimited number of
+     times, the use of a once-only subpattern is the only way  to
+     avoid  some  failing matches taking a very long time indeed.
+     The pattern
+
+       (\D+|<\d+>)*[!?]
+
+     matches an unlimited number of substrings that  either  con-
+     sist  of  non-digits,  or digits enclosed in <>, followed by
+     either ! or ?. When it matches, it runs quickly. However, if
+     it is applied to
+
+       aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
+
+     it takes a long  time  before  reporting  failure.  This  is
+     because the string can be divided between the two repeats in
+     a large number of ways, and all have to be tried. (The exam-
+     ple  used  [!?]  rather  than a single character at the end,
+     because both PCRE and Perl have an optimization that  allows
+     for  fast  failure  when  a  single  character is used. They
+     remember the last single character that is  required  for  a
+     match,  and  fail early if it is not present in the string.)
+     If the pattern is changed to
+
+       ((?>\D+)|<\d+>)*[!?]
+
+     sequences of non-digits cannot be broken, and  failure  hap-
+     pens quickly.
+
+
+
+CONDITIONAL SUBPATTERNS
+     It is possible to cause the matching process to obey a  sub-
+     pattern  conditionally  or to choose between two alternative
+     subpatterns, depending on the result  of  an  assertion,  or
+     whether  a previous capturing subpattern matched or not. The
+     two possible forms of conditional subpattern are
+
+       (?(condition)yes-pattern)
+       (?(condition)yes-pattern|no-pattern)
+
+     If the condition is satisfied, the yes-pattern is used; oth-
+     erwise  the  no-pattern  (if  present) is used. If there are
+     more than two alternatives in the subpattern, a compile-time
+     error occurs.
+
+     There are two kinds of condition. If the  text  between  the
+     parentheses  consists  of  a  sequence  of  digits, then the
+     condition is satisfied if the capturing subpattern  of  that
+     number  has  previously matched. Consider the following pat-
+     tern, which contains non-significant white space to make  it
+     more  readable  (assume  the  PCRE_EXTENDED  option)  and to
+     divide it into three parts for ease of discussion:
+
+       ( \( )?    [^()]+    (?(1) \) )
+
+     The first part matches an optional opening parenthesis,  and
+     if  that character is present, sets it as the first captured
+     substring. The second part matches one  or  more  characters
+     that  are  not  parentheses. The third part is a conditional
+     subpattern that tests whether the first set  of  parentheses
+     matched  or  not.  If  they did, that is, if subject started
+     with an opening parenthesis, the condition is true,  and  so
+     the  yes-pattern  is  executed  and a closing parenthesis is
+     required. Otherwise, since no-pattern is  not  present,  the
+     subpattern  matches  nothing.  In  other words, this pattern
+     matches a sequence of non-parentheses,  optionally  enclosed
+     in parentheses.
+
+     If the condition is not a sequence of digits, it must be  an
+     assertion.  This  may be a positive or negative lookahead or
+     lookbehind assertion. Consider this pattern, again  contain-
+     ing  non-significant  white space, and with the two alterna-
+     tives on the second line:
+
+       (?(?=[^a-z]*[a-z])
+       \d{2}-[a-z]{3}-\d{2}  |  \d{2}-\d{2}-\d{2} )
+
+     The condition is a positive lookahead assertion that matches
+     an optional sequence of non-letters followed by a letter. In
+     other words, it tests for  the  presence  of  at  least  one
+     letter  in the subject. If a letter is found, the subject is
+     matched against  the  first  alternative;  otherwise  it  is
+     matched  against the second. This pattern matches strings in
+     one of the two forms dd-aaa-dd or dd-dd-dd,  where  aaa  are
+     letters and dd are digits.
+
+
+
+COMMENTS
+     The sequence (?# marks the start of a comment which  contin-
+     ues  up  to the next closing parenthesis. Nested parentheses
+     are not permitted. The characters that  make  up  a  comment
+     play no part in the pattern matching at all.
+
+     If the PCRE_EXTENDED option is set, an unescaped # character
+     outside  a character class introduces a comment that contin-
+     ues up to the next newline character in the pattern.
+
+
+
+RECURSIVE PATTERNS
+     Consider the problem of matching a  string  in  parentheses,
+     allowing  for  unlimited nested parentheses. Without the use
+     of recursion, the best that can be done is to use a  pattern
+     that  matches  up  to some fixed depth of nesting. It is not
+     possible to handle an arbitrary nesting depth. Perl 5.6  has
+     provided   an  experimental  facility  that  allows  regular
+     expressions to recurse (amongst other things). It does  this
+     by  interpolating  Perl  code in the expression at run time,
+     and the code can refer to the expression itself. A Perl pat-
+     tern  to  solve  the parentheses problem can be created like
+     this:
+
+       $re = qr{\( (?: (?>[^()]+) | (?p{$re}) )* \)}x;
+
+     The (?p{...}) item interpolates Perl code at run  time,  and
+     in  this  case refers recursively to the pattern in which it
+     appears. Obviously, PCRE cannot support the interpolation of
+     Perl  code.  Instead,  the special item (?R) is provided for
+     the specific case of recursion. This PCRE pattern solves the
+     parentheses  problem (assume the PCRE_EXTENDED option is set
+     so that white space is ignored):
+
+       \( ( (?>[^()]+) | (?R) )* \)
+
+     First it matches an opening parenthesis. Then it matches any
+     number  of substrings which can either be a sequence of non-
+     parentheses, or a recursive  match  of  the  pattern  itself
+     (i.e. a correctly parenthesized substring). Finally there is
+     a closing parenthesis.
+
+     This particular example pattern  contains  nested  unlimited
+     repeats, and so the use of a once-only subpattern for match-
+     ing strings of non-parentheses is  important  when  applying
+     the  pattern to strings that do not match. For example, when
+     it is applied to
+
+       (aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa()
+
+     it yields "no match" quickly. However, if a  once-only  sub-
+     pattern  is  not  used,  the match runs for a very long time
+     indeed because there are so many different ways the + and  *
+     repeats  can carve up the subject, and all have to be tested
+     before failure can be reported.
+
+     The values set for any capturing subpatterns are those  from
+     the outermost level of the recursion at which the subpattern
+     value is set. If the pattern above is matched against
+
+       (ab(cd)ef)
+
+     the value for the capturing parentheses is  "ef",  which  is
+     the  last  value  taken  on  at the top level. If additional
+     parentheses are added, giving
+
+       \( ( ( (?>[^()]+) | (?R) )* ) \)
+          ^                        ^
+          ^                        ^ then the string they capture
+     is "ab(cd)ef", the contents of the top level parentheses. If
+     there are more than 15 capturing parentheses in  a  pattern,
+     PCRE  has  to  obtain  extra  memory  to store data during a
+     recursion, which it does by using  pcre_malloc,  freeing  it
+     via  pcre_free  afterwards. If no memory can be obtained, it
+     saves data for the first 15 capturing parentheses  only,  as
+     there is no way to give an out-of-memory error from within a
+     recursion.
+
+
+
+PERFORMANCE
+     Certain items that may appear in patterns are more efficient
+     than  others.  It is more efficient to use a character class
+     like [aeiou] than a set of alternatives such as (a|e|i|o|u).
+     In  general,  the  simplest  construction  that provides the
+     required behaviour is usually the  most  efficient.  Jeffrey
+     Friedl's  book contains a lot of discussion about optimizing
+     regular expressions for efficient performance.
+
+     When a pattern begins with .* and the PCRE_DOTALL option  is
+     set,  the  pattern  is implicitly anchored by PCRE, since it
+     can match only at the start of a subject string. However, if
+     PCRE_DOTALL  is not set, PCRE cannot make this optimization,
+     because the . metacharacter does not then match  a  newline,
+     and if the subject string contains newlines, the pattern may
+     match from the character immediately following one  of  them
+     instead of from the very start. For example, the pattern
+
+       (.*) second
+
+     matches the subject "first\nand second" (where \n stands for
+     a newline character) with the first captured substring being
+     "and". In order to do this, PCRE  has  to  retry  the  match
+     starting after every newline in the subject.
+
+     If you are using such a pattern with subject strings that do
+     not  contain  newlines,  the best performance is obtained by
+     setting PCRE_DOTALL, or starting the  pattern  with  ^.*  to
+     indicate  explicit anchoring. That saves PCRE from having to
+     scan along the subject looking for a newline to restart at.
+
+     Beware of patterns that contain nested  indefinite  repeats.
+     These  can  take a long time to run when applied to a string
+     that does not match. Consider the pattern fragment
+
+       (a+)*
+
+     This can match "aaaa" in 33 different ways, and this  number
+     increases  very  rapidly  as  the string gets longer. (The *
+     repeat can match 0, 1, 2, 3, or 4 times,  and  for  each  of
+     those  cases other than 0, the + repeats can match different
+     numbers of times.) When the remainder of the pattern is such
+     that  the entire match is going to fail, PCRE has in princi-
+     ple to try every possible variation, and this  can  take  an
+     extremely long time.
+
+     An optimization catches some of the more simple  cases  such
+     as
+
+       (a+)*b
+
+     where a literal character follows. Before embarking  on  the
+     standard matching procedure, PCRE checks that there is a "b"
+     later in the subject string, and if there is not,  it  fails
+     the  match  immediately. However, when there is no following
+     literal this optimization cannot be used. You  can  see  the
+     difference by comparing the behaviour of
+
+       (a+)*\d
+
+     with the pattern above. The former gives  a  failure  almost
+     instantly  when  applied  to a whole line of "a" characters,
+     whereas the latter takes an appreciable  time  with  strings
+     longer than about 20 characters.
+
+
+
+AUTHOR
+     Philip Hazel <ph10@cam.ac.uk>
+     University Computing Service,
+     New Museums Site,
+     Cambridge CB2 3QG, England.
+     Phone: +44 1223 334714
+
+     Last updated: 27 January 2000
+     Copyright (c) 1997-2000 University of Cambridge.
diff --git a/ext/pcre/pcrelib/doc/pcreposix.3 b/ext/pcre/pcrelib/doc/pcreposix.3
new file mode 100644 (file)
index 0000000..1be5d9a
--- /dev/null
@@ -0,0 +1,141 @@
+.TH PCRE 3
+.SH NAME
+pcreposix - POSIX API for Perl-compatible regular expressions.
+.SH SYNOPSIS
+.B #include <pcreposix.h>
+.PP
+.SM
+.br
+.B int regcomp(regex_t *\fIpreg\fR, const char *\fIpattern\fR,
+.ti +5n
+.B int \fIcflags\fR);
+.PP
+.br
+.B int regexec(regex_t *\fIpreg\fR, const char *\fIstring\fR,
+.ti +5n
+.B size_t \fInmatch\fR, regmatch_t \fIpmatch\fR[], int \fIeflags\fR);
+.PP
+.br
+.B size_t regerror(int \fIerrcode\fR, const regex_t *\fIpreg\fR,
+.ti +5n
+.B char *\fIerrbuf\fR, size_t \fIerrbuf_size\fR);
+.PP
+.br
+.B void regfree(regex_t *\fIpreg\fR);
+
+
+.SH DESCRIPTION
+This set of functions provides a POSIX-style API to the PCRE regular expression
+package. See the \fBpcre\fR documentation for a description of the native API,
+which contains additional functionality.
+
+The functions described here are just wrapper functions that ultimately call
+the native API. Their prototypes are defined in the \fBpcreposix.h\fR header
+file, and on Unix systems the library itself is called \fBpcreposix.a\fR, so
+can be accessed by adding \fB-lpcreposix\fR to the command for linking an
+application which uses them. Because the POSIX functions call the native ones,
+it is also necessary to add \fR-lpcre\fR.
+
+I have implemented only those option bits that can be reasonably mapped to PCRE
+native options. In addition, the options REG_EXTENDED and REG_NOSUB are defined
+with the value zero. They have no effect, but since programs that are written
+to the POSIX interface often use them, this makes it easier to slot in PCRE as
+a replacement library. Other POSIX options are not even defined.
+
+When PCRE is called via these functions, it is only the API that is POSIX-like
+in style. The syntax and semantics of the regular expressions themselves are
+still those of Perl, subject to the setting of various PCRE options, as
+described below.
+
+The header for these functions is supplied as \fBpcreposix.h\fR to avoid any
+potential clash with other POSIX libraries. It can, of course, be renamed or
+aliased as \fBregex.h\fR, which is the "correct" name. It provides two
+structure types, \fIregex_t\fR for compiled internal forms, and
+\fIregmatch_t\fR for returning captured substrings. It also defines some
+constants whose names start with "REG_"; these are used for setting options and
+identifying error codes.
+
+
+.SH COMPILING A PATTERN
+
+The function \fBregcomp()\fR is called to compile a pattern into an
+internal form. The pattern is a C string terminated by a binary zero, and
+is passed in the argument \fIpattern\fR. The \fIpreg\fR argument is a pointer
+to a regex_t structure which is used as a base for storing information about
+the compiled expression.
+
+The argument \fIcflags\fR is either zero, or contains one or more of the bits
+defined by the following macros:
+
+  REG_ICASE
+
+The PCRE_CASELESS option is set when the expression is passed for compilation
+to the native function.
+
+  REG_NEWLINE
+
+The PCRE_MULTILINE option is set when the expression is passed for compilation
+to the native function.
+
+The yield of \fBregcomp()\fR is zero on success, and non-zero otherwise. The
+\fIpreg\fR structure is filled in on success, and one member of the structure
+is publicized: \fIre_nsub\fR contains the number of capturing subpatterns in
+the regular expression. Various error codes are defined in the header file.
+
+
+.SH MATCHING A PATTERN
+The function \fBregexec()\fR is called to match a pre-compiled pattern
+\fIpreg\fR against a given \fIstring\fR, which is terminated by a zero byte,
+subject to the options in \fIeflags\fR. These can be:
+
+  REG_NOTBOL
+
+The PCRE_NOTBOL option is set when calling the underlying PCRE matching
+function.
+
+  REG_NOTEOL
+
+The PCRE_NOTEOL option is set when calling the underlying PCRE matching
+function.
+
+The portion of the string that was matched, and also any captured substrings,
+are returned via the \fIpmatch\fR argument, which points to an array of
+\fInmatch\fR structures of type \fIregmatch_t\fR, containing the members
+\fIrm_so\fR and \fIrm_eo\fR. These contain the offset to the first character of
+each substring and the offset to the first character after the end of each
+substring, respectively. The 0th element of the vector relates to the entire
+portion of \fIstring\fR that was matched; subsequent elements relate to the
+capturing subpatterns of the regular expression. Unused entries in the array
+have both structure members set to -1.
+
+A successful match yields a zero return; various error codes are defined in the
+header file, of which REG_NOMATCH is the "expected" failure code.
+
+
+.SH ERROR MESSAGES
+The \fBregerror()\fR function maps a non-zero errorcode from either
+\fBregcomp\fR or \fBregexec\fR to a printable message. If \fIpreg\fR is not
+NULL, the error should have arisen from the use of that structure. A message
+terminated by a binary zero is placed in \fIerrbuf\fR. The length of the
+message, including the zero, is limited to \fIerrbuf_size\fR. The yield of the
+function is the size of buffer needed to hold the whole message.
+
+
+.SH STORAGE
+Compiling a regular expression causes memory to be allocated and associated
+with the \fIpreg\fR structure. The function \fBregfree()\fR frees all such
+memory, after which \fIpreg\fR may no longer be used as a compiled expression.
+
+
+.SH AUTHOR
+Philip Hazel <ph10@cam.ac.uk>
+.br
+University Computing Service,
+.br
+New Museums Site,
+.br
+Cambridge CB2 3QG, England.
+.br
+Phone: +44 1223 334714
+
+Copyright (c) 1997-1999 University of Cambridge.
diff --git a/ext/pcre/pcrelib/doc/pcreposix.html b/ext/pcre/pcrelib/doc/pcreposix.html
new file mode 100644 (file)
index 0000000..121d90f
--- /dev/null
@@ -0,0 +1,182 @@
+<HTML>
+<HEAD>
+<TITLE>pcreposix specification</TITLE>
+</HEAD>
+<body bgcolor="#FFFFFF" text="#00005A">
+<H1>pcreposix specification</H1>
+This HTML document has been generated automatically from the original man page.
+If there is any nonsense in it, please consult the man page in case the
+conversion went wrong.
+<UL>
+<LI><A NAME="TOC1" HREF="#SEC1">NAME</A>
+<LI><A NAME="TOC2" HREF="#SEC2">SYNOPSIS</A>
+<LI><A NAME="TOC3" HREF="#SEC3">DESCRIPTION</A>
+<LI><A NAME="TOC4" HREF="#SEC4">COMPILING A PATTERN</A>
+<LI><A NAME="TOC5" HREF="#SEC5">MATCHING A PATTERN</A>
+<LI><A NAME="TOC6" HREF="#SEC6">ERROR MESSAGES</A>
+<LI><A NAME="TOC7" HREF="#SEC7">STORAGE</A>
+<LI><A NAME="TOC8" HREF="#SEC8">AUTHOR</A>
+</UL>
+<LI><A NAME="SEC1" HREF="#TOC1">NAME</A>
+<P>
+pcreposix - POSIX API for Perl-compatible regular expressions.
+</P>
+<LI><A NAME="SEC2" HREF="#TOC1">SYNOPSIS</A>
+<P>
+<B>#include &#60;pcreposix.h&#62;</B>
+</P>
+<P>
+<B>int regcomp(regex_t *<I>preg</I>, const char *<I>pattern</I>,</B>
+<B>int <I>cflags</I>);</B>
+</P>
+<P>
+<B>int regexec(regex_t *<I>preg</I>, const char *<I>string</I>,</B>
+<B>size_t <I>nmatch</I>, regmatch_t <I>pmatch</I>[], int <I>eflags</I>);</B>
+</P>
+<P>
+<B>size_t regerror(int <I>errcode</I>, const regex_t *<I>preg</I>,</B>
+<B>char *<I>errbuf</I>, size_t <I>errbuf_size</I>);</B>
+</P>
+<P>
+<B>void regfree(regex_t *<I>preg</I>);</B>
+</P>
+<LI><A NAME="SEC3" HREF="#TOC1">DESCRIPTION</A>
+<P>
+This set of functions provides a POSIX-style API to the PCRE regular expression
+package. See the <B>pcre</B> documentation for a description of the native API,
+which contains additional functionality.
+</P>
+<P>
+The functions described here are just wrapper functions that ultimately call
+the native API. Their prototypes are defined in the <B>pcreposix.h</B> header
+file, and on Unix systems the library itself is called <B>pcreposix.a</B>, so
+can be accessed by adding <B>-lpcreposix</B> to the command for linking an
+application which uses them. Because the POSIX functions call the native ones,
+it is also necessary to add \fR-lpcre\fR.
+</P>
+<P>
+I have implemented only those option bits that can be reasonably mapped to PCRE
+native options. In addition, the options REG_EXTENDED and REG_NOSUB are defined
+with the value zero. They have no effect, but since programs that are written
+to the POSIX interface often use them, this makes it easier to slot in PCRE as
+a replacement library. Other POSIX options are not even defined.
+</P>
+<P>
+When PCRE is called via these functions, it is only the API that is POSIX-like
+in style. The syntax and semantics of the regular expressions themselves are
+still those of Perl, subject to the setting of various PCRE options, as
+described below.
+</P>
+<P>
+The header for these functions is supplied as <B>pcreposix.h</B> to avoid any
+potential clash with other POSIX libraries. It can, of course, be renamed or
+aliased as <B>regex.h</B>, which is the "correct" name. It provides two
+structure types, <I>regex_t</I> for compiled internal forms, and
+<I>regmatch_t</I> for returning captured substrings. It also defines some
+constants whose names start with "REG_"; these are used for setting options and
+identifying error codes.
+</P>
+<LI><A NAME="SEC4" HREF="#TOC1">COMPILING A PATTERN</A>
+<P>
+The function <B>regcomp()</B> is called to compile a pattern into an
+internal form. The pattern is a C string terminated by a binary zero, and
+is passed in the argument <I>pattern</I>. The <I>preg</I> argument is a pointer
+to a regex_t structure which is used as a base for storing information about
+the compiled expression.
+</P>
+<P>
+The argument <I>cflags</I> is either zero, or contains one or more of the bits
+defined by the following macros:
+</P>
+<P>
+<PRE>
+  REG_ICASE
+</PRE>
+</P>
+<P>
+The PCRE_CASELESS option is set when the expression is passed for compilation
+to the native function.
+</P>
+<P>
+<PRE>
+  REG_NEWLINE
+</PRE>
+</P>
+<P>
+The PCRE_MULTILINE option is set when the expression is passed for compilation
+to the native function.
+</P>
+<P>
+The yield of <B>regcomp()</B> is zero on success, and non-zero otherwise. The
+<I>preg</I> structure is filled in on success, and one member of the structure
+is publicized: <I>re_nsub</I> contains the number of capturing subpatterns in
+the regular expression. Various error codes are defined in the header file.
+</P>
+<LI><A NAME="SEC5" HREF="#TOC1">MATCHING A PATTERN</A>
+<P>
+The function <B>regexec()</B> is called to match a pre-compiled pattern
+<I>preg</I> against a given <I>string</I>, which is terminated by a zero byte,
+subject to the options in <I>eflags</I>. These can be:
+</P>
+<P>
+<PRE>
+  REG_NOTBOL
+</PRE>
+</P>
+<P>
+The PCRE_NOTBOL option is set when calling the underlying PCRE matching
+function.
+</P>
+<P>
+<PRE>
+  REG_NOTEOL
+</PRE>
+</P>
+<P>
+The PCRE_NOTEOL option is set when calling the underlying PCRE matching
+function.
+</P>
+<P>
+The portion of the string that was matched, and also any captured substrings,
+are returned via the <I>pmatch</I> argument, which points to an array of
+<I>nmatch</I> structures of type <I>regmatch_t</I>, containing the members
+<I>rm_so</I> and <I>rm_eo</I>. These contain the offset to the first character of
+each substring and the offset to the first character after the end of each
+substring, respectively. The 0th element of the vector relates to the entire
+portion of <I>string</I> that was matched; subsequent elements relate to the
+capturing subpatterns of the regular expression. Unused entries in the array
+have both structure members set to -1.
+</P>
+<P>
+A successful match yields a zero return; various error codes are defined in the
+header file, of which REG_NOMATCH is the "expected" failure code.
+</P>
+<LI><A NAME="SEC6" HREF="#TOC1">ERROR MESSAGES</A>
+<P>
+The <B>regerror()</B> function maps a non-zero errorcode from either
+<B>regcomp</B> or <B>regexec</B> to a printable message. If <I>preg</I> is not
+NULL, the error should have arisen from the use of that structure. A message
+terminated by a binary zero is placed in <I>errbuf</I>. The length of the
+message, including the zero, is limited to <I>errbuf_size</I>. The yield of the
+function is the size of buffer needed to hold the whole message.
+</P>
+<LI><A NAME="SEC7" HREF="#TOC1">STORAGE</A>
+<P>
+Compiling a regular expression causes memory to be allocated and associated
+with the <I>preg</I> structure. The function <B>regfree()</B> frees all such
+memory, after which <I>preg</I> may no longer be used as a compiled expression.
+</P>
+<LI><A NAME="SEC8" HREF="#TOC1">AUTHOR</A>
+<P>
+Philip Hazel &#60;ph10@cam.ac.uk&#62;
+<BR>
+University Computing Service,
+<BR>
+New Museums Site,
+<BR>
+Cambridge CB2 3QG, England.
+<BR>
+Phone: +44 1223 334714
+</P>
+<P>
+Copyright (c) 1997-1999 University of Cambridge.
diff --git a/ext/pcre/pcrelib/doc/pcreposix.txt b/ext/pcre/pcrelib/doc/pcreposix.txt
new file mode 100644 (file)
index 0000000..4a7036f
--- /dev/null
@@ -0,0 +1,150 @@
+NAME
+     pcreposix - POSIX API for  Perl-compatible  regular  expres-
+     sions.
+
+
+
+SYNOPSIS
+     #include <pcreposix.h>
+
+     int regcomp(regex_t *preg, const char *pattern,
+          int cflags);
+
+     int regexec(regex_t *preg, const char *string,
+          size_t nmatch, regmatch_t pmatch[], int eflags);
+
+     size_t regerror(int errcode, const regex_t *preg,
+          char *errbuf, size_t errbuf_size);
+
+     void regfree(regex_t *preg);
+
+
+
+DESCRIPTION
+     This set of functions provides a POSIX-style API to the PCRE
+     regular expression package. See the pcre documentation for a
+     description of the native  API,  which  contains  additional
+     functionality.
+
+     The functions described here are just wrapper functions that
+     ultimately call the native API. Their prototypes are defined
+     in the pcreposix.h header file,  and  on  Unix  systems  the
+     library  itself is called pcreposix.a, so can be accessed by
+     adding -lpcreposix to the command for linking an application
+     which uses them. Because the POSIX functions call the native
+     ones, it is also necessary to add -lpcre.
+
+     I have implemented only those option bits that can  be  rea-
+     sonably  mapped  to  PCRE  native  options. In addition, the
+     options REG_EXTENDED and  REG_NOSUB  are  defined  with  the
+     value zero. They have no effect, but since programs that are
+     written to the POSIX interface often use them, this makes it
+     easier to slot in PCRE as a replacement library. Other POSIX
+     options are not even defined.
+
+     When PCRE is called via these functions, it is only the  API
+     that is POSIX-like in style. The syntax and semantics of the
+     regular expressions themselves are still those of Perl, sub-
+     ject  to  the  setting of various PCRE options, as described
+     below.
+
+     The header for these functions is supplied as pcreposix.h to
+     avoid  any  potential  clash  with other POSIX libraries. It
+     can, of course, be renamed or aliased as regex.h,  which  is
+     the "correct" name. It provides two structure types, regex_t
+     for compiled internal forms, and  regmatch_t  for  returning
+     captured  substrings.  It  also defines some constants whose
+     names start with "REG_"; these are used for setting  options
+     and identifying error codes.
+
+
+
+COMPILING A PATTERN
+     The function regcomp() is called to compile a  pattern  into
+     an  internal form. The pattern is a C string terminated by a
+     binary zero, and is passed in the argument pattern. The preg
+     argument  is  a pointer to a regex_t structure which is used
+     as a base for storing information about the compiled expres-
+     sion.
+
+     The argument cflags is either zero, or contains one or  more
+     of the bits defined by the following macros:
+
+       REG_ICASE
+
+     The PCRE_CASELESS option  is  set  when  the  expression  is
+     passed for compilation to the native function.
+
+       REG_NEWLINE
+
+     The PCRE_MULTILINE option is  set  when  the  expression  is
+     passed for compilation to the native function.
+
+     The yield of regcomp() is zero on success, and non-zero oth-
+     erwise.  The preg structure is filled in on success, and one
+     member of the structure is publicized: re_nsub contains  the
+     number  of  capturing subpatterns in the regular expression.
+     Various error codes are defined in the header file.
+
+
+
+MATCHING A PATTERN
+     The function regexec() is called  to  match  a  pre-compiled
+     pattern  preg against a given string, which is terminated by
+     a zero byte, subject to the options in eflags. These can be:
+
+       REG_NOTBOL
+
+     The PCRE_NOTBOL option is set when  calling  the  underlying
+     PCRE matching function.
+
+       REG_NOTEOL
+
+     The PCRE_NOTEOL option is set when  calling  the  underlying
+     PCRE matching function.
+
+     The portion of the string that was  matched,  and  also  any
+     captured  substrings,  are returned via the pmatch argument,
+     which points to  an  array  of  nmatch  structures  of  type
+     regmatch_t,  containing  the  members rm_so and rm_eo. These
+     contain the offset to the first character of each  substring
+     and  the offset to the first character after the end of each
+     substring, respectively.  The  0th  element  of  the  vector
+     relates  to  the  entire portion of string that was matched;
+     subsequent elements relate to the capturing  subpatterns  of
+     the  regular  expression.  Unused  entries in the array have
+     both structure members set to -1.
+
+     A successful match yields a zero return; various error codes
+     are  defined in the header file, of which REG_NOMATCH is the
+     "expected" failure code.
+
+
+
+ERROR MESSAGES
+     The regerror()  function  maps  a  non-zero  errorcode  from
+     either regcomp or regexec to a printable message. If preg is
+     not NULL, the error should have arisen from the use of  that
+     structure.  A  message terminated by a binary zero is placed
+     in errbuf. The length of the message, including the zero, is
+     limited  to  errbuf_size.  The  yield of the function is the
+     size of buffer needed to hold the whole message.
+
+
+
+STORAGE
+     Compiling a regular expression causes memory to be allocated
+     and  associated  with  the preg structure. The function reg-
+     free() frees all such memory, after which preg may no longer
+     be used as a compiled expression.
+
+
+
+AUTHOR
+     Philip Hazel <ph10@cam.ac.uk>
+     University Computing Service,
+     New Museums Site,
+     Cambridge CB2 3QG, England.
+     Phone: +44 1223 334714
+
+     Copyright (c) 1997-1999 University of Cambridge.
diff --git a/ext/pcre/pcrelib/doc/pcretest.txt b/ext/pcre/pcrelib/doc/pcretest.txt
new file mode 100644 (file)
index 0000000..831fdac
--- /dev/null
@@ -0,0 +1,216 @@
+The pcretest program
+--------------------
+
+This program is intended for testing PCRE, but it can also be used for
+experimenting with regular expressions.
+
+If it is given two filename arguments, it reads from the first and writes to
+the second. If it is given only one filename argument, it reads from that file
+and writes to stdout. Otherwise, it reads from stdin and writes to stdout, and
+prompts for each line of input, using "re>" to prompt for regular expressions,
+and "data>" to prompt for data lines.
+
+The program handles any number of sets of input on a single input file. Each
+set starts with a regular expression, and continues with any number of data
+lines to be matched against the pattern. An empty line signals the end of the
+data lines, at which point a new regular expression is read. The regular
+expressions are given enclosed in any non-alphameric delimiters other than
+backslash, for example
+
+  /(a|bc)x+yz/
+
+White space before the initial delimiter is ignored. A regular expression may
+be continued over several input lines, in which case the newline characters are
+included within it. See the test input files in the testdata directory for many
+examples. It is possible to include the delimiter within the pattern by
+escaping it, for example
+
+  /abc\/def/
+
+If you do so, the escape and the delimiter form part of the pattern, but since
+delimiters are always non-alphameric, this does not affect its interpretation.
+If the terminating delimiter is immediately followed by a backslash, for
+example,
+
+  /abc/\
+
+then a backslash is added to the end of the pattern. This is done to provide a
+way of testing the error condition that arises if a pattern finishes with a
+backslash, because
+
+  /abc\/
+
+is interpreted as the first line of a pattern that starts with "abc/", causing
+pcretest to read the next line as a continuation of the regular expression.
+
+The pattern may be followed by i, m, s, or x to set the PCRE_CASELESS,
+PCRE_MULTILINE, PCRE_DOTALL, or PCRE_EXTENDED options, respectively. For
+example:
+
+  /caseless/i
+
+These modifier letters have the same effect as they do in Perl. There are
+others which set PCRE options that do not correspond to anything in Perl: /A,
+/E, and /X set PCRE_ANCHORED, PCRE_DOLLAR_ENDONLY, and PCRE_EXTRA respectively.
+
+Searching for all possible matches within each subject string can be requested
+by the /g or /G modifier. After finding a match, PCRE is called again to search
+the remainder of the subject string. The difference between /g and /G is that
+the former uses the startoffset argument to pcre_exec() to start searching at
+a new point within the entire string (which is in effect what Perl does),
+whereas the latter passes over a shortened substring. This makes a difference
+to the matching process if the pattern begins with a lookbehind assertion
+(including \b or \B).
+
+If any call to pcre_exec() in a /g or /G sequence matches an empty string, the
+next call is done with the PCRE_NOTEMPTY flag set so that it cannot match an
+empty string again at the same point. If however, this second match fails, the
+start offset is advanced by one, and the match is retried. This imitates the
+way Perl handles such cases when using the /g modifier or the split() function.
+
+There are a number of other modifiers for controlling the way pcretest
+operates.
+
+The /+ modifier requests that as well as outputting the substring that matched
+the entire pattern, pcretest should in addition output the remainder of the
+subject string. This is useful for tests where the subject contains multiple
+copies of the same substring.
+
+The /L modifier must be followed directly by the name of a locale, for example,
+
+  /pattern/Lfr
+
+For this reason, it must be the last modifier letter. The given locale is set,
+pcre_maketables() is called to build a set of character tables for the locale,
+and this is then passed to pcre_compile() when compiling the regular
+expression. Without an /L modifier, NULL is passed as the tables pointer; that
+is, /L applies only to the expression on which it appears.
+
+The /I modifier requests that pcretest output information about the compiled
+expression (whether it is anchored, has a fixed first character, and so on). It
+does this by calling pcre_fullinfo() after compiling an expression, and
+outputting the information it gets back. If the pattern is studied, the results
+of that are also output.
+
+The /D modifier is a PCRE debugging feature, which also assumes /I. It causes
+the internal form of compiled regular expressions to be output after
+compilation.
+
+The /S modifier causes pcre_study() to be called after the expression has been
+compiled, and the results used when the expression is matched.
+
+The /M modifier causes the size of memory block used to hold the compiled
+pattern to be output.
+
+Finally, the /P modifier causes pcretest to call PCRE via the POSIX wrapper API
+rather than its native API. When this is done, all other modifiers except /i,
+/m, and /+ are ignored. REG_ICASE is set if /i is present, and REG_NEWLINE is
+set if /m is present. The wrapper functions force PCRE_DOLLAR_ENDONLY always,
+and PCRE_DOTALL unless REG_NEWLINE is set.
+
+Before each data line is passed to pcre_exec(), leading and trailing whitespace
+is removed, and it is then scanned for \ escapes. The following are recognized:
+
+  \a     alarm (= BEL)
+  \b     backspace
+  \e     escape
+  \f     formfeed
+  \n     newline
+  \r     carriage return
+  \t     tab
+  \v     vertical tab
+  \nnn   octal character (up to 3 octal digits)
+  \xhh   hexadecimal character (up to 2 hex digits)
+
+  \A     pass the PCRE_ANCHORED option to pcre_exec()
+  \B     pass the PCRE_NOTBOL option to pcre_exec()
+  \Cdd   call pcre_copy_substring() for substring dd after a successful match
+           (any decimal number less than 32)
+  \Gdd   call pcre_get_substring() for substring dd after a successful match
+           (any decimal number less than 32)
+  \L     call pcre_get_substringlist() after a successful match
+  \N     pass the PCRE_NOTEMPTY option to pcre_exec()
+  \Odd   set the size of the output vector passed to pcre_exec() to dd
+           (any number of decimal digits)
+  \Z     pass the PCRE_NOTEOL option to pcre_exec()
+
+A backslash followed by anything else just escapes the anything else. If the
+very last character is a backslash, it is ignored. This gives a way of passing
+an empty line as data, since a real empty line terminates the data input.
+
+If /P was present on the regex, causing the POSIX wrapper API to be used, only
+\B, and \Z have any effect, causing REG_NOTBOL and REG_NOTEOL to be passed to
+regexec() respectively.
+
+When a match succeeds, pcretest outputs the list of captured substrings that
+pcre_exec() returns, starting with number 0 for the string that matched the
+whole pattern. Here is an example of an interactive pcretest run.
+
+  $ pcretest
+  PCRE version 2.06 08-Jun-1999
+
+    re> /^abc(\d+)/
+  data> abc123
+   0: abc123
+   1: 123
+  data> xyz
+  No match
+
+If the strings contain any non-printing characters, they are output as \0x
+escapes. If the pattern has the /+ modifier, then the output for substring 0 is
+followed by the the rest of the subject string, identified by "0+" like this:
+
+    re> /cat/+
+  data> cataract
+   0: cat
+   0+ aract
+
+If the pattern has the /g or /G modifier, the results of successive matching
+attempts are output in sequence, like this:
+
+    re> /\Bi(\w\w)/g
+  data> Mississippi
+   0: iss
+   1: ss
+   0: iss
+   1: ss
+   0: ipp
+   1: pp
+
+"No match" is output only if the first match attempt fails.
+
+If any of \C, \G, or \L are present in a data line that is successfully
+matched, the substrings extracted by the convenience functions are output with
+C, G, or L after the string number instead of a colon. This is in addition to
+the normal full list. The string length (that is, the return from the
+extraction function) is given in parentheses after each string for \C and \G.
+
+Note that while patterns can be continued over several lines (a plain ">"
+prompt is used for continuations), data lines may not. However newlines can be
+included in data by means of the \n escape.
+
+If the -p option is given to pcretest, it is equivalent to adding /P to each
+regular expression: the POSIX wrapper API is used to call PCRE. None of the
+following flags has any effect in this case.
+
+If the option -d is given to pcretest, it is equivalent to adding /D to each
+regular expression: the internal form is output after compilation.
+
+If the option -i is given to pcretest, it is equivalent to adding /I to each
+regular expression: information about the compiled pattern is given after
+compilation.
+
+If the option -m is given to pcretest, it outputs the size of each compiled
+pattern after it has been compiled. It is equivalent to adding /M to each
+regular expression. For compatibility with earlier versions of pcretest, -s is
+a synonym for -m.
+
+If the -t option is given, each compile, study, and match is run 20000 times
+while being timed, and the resulting time per compile or match is output in
+milliseconds. Do not set -t with -s, because you will then get the size output
+20000 times and the timing will be distorted. If you want to change the number
+of repetitions used for timing, edit the definition of LOOPREPEAT at the top of
+pcretest.c
+
+Philip Hazel <ph10@cam.ac.uk>
+January 2000
diff --git a/ext/pcre/pcrelib/doc/perltest.txt b/ext/pcre/pcrelib/doc/perltest.txt
new file mode 100644 (file)
index 0000000..6c38ebe
--- /dev/null
@@ -0,0 +1,23 @@
+The perltest program
+--------------------
+
+The perltest program tests Perl's regular expressions; it has the same
+specification as pcretest, and so can be given identical input, except that
+input patterns can be followed only by Perl's lower case modifiers and /+ (as
+used by pcretest), which is recognized and handled by the program.
+
+The data lines are processed as Perl double-quoted strings, so if they contain
+" \ $ or @ characters, these have to be escaped. For this reason, all such
+characters in testinput1 and testinput3 are escaped so that they can be used
+for perltest as well as for pcretest, and the special upper case modifiers such
+as /A that pcretest recognizes are not used in these files. The output should
+be identical, apart from the initial identifying banner.
+
+The testinput2 and testinput4 files are not suitable for feeding to perltest,
+since they do make use of the special upper case modifiers and escapes that
+pcretest uses to test some features of PCRE. The first of these files also
+contains malformed regular expressions, in order to check that PCRE diagnoses
+them correctly.
+
+Philip Hazel <ph10@cam.ac.uk>
+January 2000
diff --git a/ext/pcre/pcrelib/doc/pgrep.1 b/ext/pcre/pcrelib/doc/pgrep.1
new file mode 100644 (file)
index 0000000..d9e9b57
--- /dev/null
@@ -0,0 +1,76 @@
+.TH PGREP 1
+.SH NAME
+pgrep - a grep with Perl-compatible regular expressions.
+.SH SYNOPSIS
+.B pgrep [-Vchilnsvx] pattern [file] ...
+
+
+.SH DESCRIPTION
+\fBpgrep\fR searches files for character patterns, in the same way as other
+grep commands do, but it uses the PCRE regular expression library to support
+patterns that are compatible with the regular expressions of Perl 5. See
+\fBpcre(3)\fR for a full description of syntax and semantics.
+
+If no files are specified, \fBpgrep\fR reads the standard input. By default,
+each line that matches the pattern is copied to the standard output, and if
+there is more than one file, the file name is printed before each line of
+output. However, there are options that can change how \fBpgrep\fR behaves.
+
+Lines are limited to BUFSIZ characters. BUFSIZ is defined in \fB<stdio.h>\fR.
+The newline character is removed from the end of each line before it is matched
+against the pattern.
+
+
+.SH OPTIONS
+.TP 10
+\fB-V\fR
+Write the version number of the PCRE library being used to the standard error
+stream.
+.TP
+\fB-c\fR
+Do not print individual lines; instead just print a count of the number of
+lines that would otherwise have been printed. If several files are given, a
+count is printed for each of them.
+.TP
+\fB-h\fR
+Suppress printing of filenames when searching multiple files.
+.TP
+\fB-i\fR
+Ignore upper/lower case distinctions during comparisons.
+.TP
+\fB-l\fR
+Instead of printing lines from the files, just print the names of the files
+containing lines that would have been printed. Each file name is printed
+once, on a separate line.
+.TP
+\fB-n\fR
+Precede each line by its line number in the file.
+.TP
+\fB-s\fR
+Work silently, that is, display nothing except error messages.
+The exit status indicates whether any matches were found.
+.TP
+\fB-v\fR
+Invert the sense of the match, so that lines which do \fInot\fR match the
+pattern are now the ones that are found.
+.TP
+\fB-x\fR
+Force the pattern to be anchored (it must start matching at the beginning of
+the line) and in addition, require it to match the entire line. This is
+equivalent to having ^ and $ characters at the start and end of each
+alternative branch in the regular expression.
+
+
+.SH SEE ALSO
+\fBpcre(3)\fR, Perl 5 documentation
+
+
+.SH DIAGNOSTICS
+Exit status is 0 if any matches were found, 1 if no matches were found, and 2
+for syntax errors or inacessible files (even if matches were found).
+
+
+.SH AUTHOR
+Philip Hazel <ph10@cam.ac.uk>
+.br
+Copyright (c) 1997-1999 University of Cambridge.
diff --git a/ext/pcre/pcrelib/doc/pgrep.html b/ext/pcre/pcrelib/doc/pgrep.html
new file mode 100644 (file)
index 0000000..54efed6
--- /dev/null
@@ -0,0 +1,105 @@
+<HTML>
+<HEAD>
+<TITLE>pgrep specification</TITLE>
+</HEAD>
+<body bgcolor="#FFFFFF" text="#00005A">
+<H1>pgrep specification</H1>
+This HTML document has been generated automatically from the original man page.
+If there is any nonsense in it, please consult the man page in case the
+conversion went wrong.
+<UL>
+<LI><A NAME="TOC1" HREF="#SEC1">NAME</A>
+<LI><A NAME="TOC2" HREF="#SEC2">SYNOPSIS</A>
+<LI><A NAME="TOC3" HREF="#SEC3">DESCRIPTION</A>
+<LI><A NAME="TOC4" HREF="#SEC4">OPTIONS</A>
+<LI><A NAME="TOC5" HREF="#SEC5">SEE ALSO</A>
+<LI><A NAME="TOC6" HREF="#SEC6">DIAGNOSTICS</A>
+<LI><A NAME="TOC7" HREF="#SEC7">AUTHOR</A>
+</UL>
+<LI><A NAME="SEC1" HREF="#TOC1">NAME</A>
+<P>
+pgrep - a grep with Perl-compatible regular expressions.
+</P>
+<LI><A NAME="SEC2" HREF="#TOC1">SYNOPSIS</A>
+<P>
+<B>pgrep [-Vchilnsvx] pattern [file] ...</B>
+</P>
+<LI><A NAME="SEC3" HREF="#TOC1">DESCRIPTION</A>
+<P>
+<B>pgrep</B> searches files for character patterns, in the same way as other
+grep commands do, but it uses the PCRE regular expression library to support
+patterns that are compatible with the regular expressions of Perl 5. See
+<B>pcre(3)</B> for a full description of syntax and semantics.
+</P>
+<P>
+If no files are specified, <B>pgrep</B> reads the standard input. By default,
+each line that matches the pattern is copied to the standard output, and if
+there is more than one file, the file name is printed before each line of
+output. However, there are options that can change how <B>pgrep</B> behaves.
+</P>
+<P>
+Lines are limited to BUFSIZ characters. BUFSIZ is defined in <B>&#60;stdio.h&#62;</B>.
+The newline character is removed from the end of each line before it is matched
+against the pattern.
+</P>
+<LI><A NAME="SEC4" HREF="#TOC1">OPTIONS</A>
+<P>
+<B>-V</B>
+Write the version number of the PCRE library being used to the standard error
+stream.
+</P>
+<P>
+<B>-c</B>
+Do not print individual lines; instead just print a count of the number of
+lines that would otherwise have been printed. If several files are given, a
+count is printed for each of them.
+</P>
+<P>
+<B>-h</B>
+Suppress printing of filenames when searching multiple files.
+</P>
+<P>
+<B>-i</B>
+Ignore upper/lower case distinctions during comparisons.
+</P>
+<P>
+<B>-l</B>
+Instead of printing lines from the files, just print the names of the files
+containing lines that would have been printed. Each file name is printed
+once, on a separate line.
+</P>
+<P>
+<B>-n</B>
+Precede each line by its line number in the file.
+</P>
+<P>
+<B>-s</B>
+Work silently, that is, display nothing except error messages.
+The exit status indicates whether any matches were found.
+</P>
+<P>
+<B>-v</B>
+Invert the sense of the match, so that lines which do <I>not</I> match the
+pattern are now the ones that are found.
+</P>
+<P>
+<B>-x</B>
+Force the pattern to be anchored (it must start matching at the beginning of
+the line) and in addition, require it to match the entire line. This is
+equivalent to having ^ and $ characters at the start and end of each
+alternative branch in the regular expression.
+</P>
+<LI><A NAME="SEC5" HREF="#TOC1">SEE ALSO</A>
+<P>
+<B>pcre(3)</B>, Perl 5 documentation
+</P>
+<LI><A NAME="SEC6" HREF="#TOC1">DIAGNOSTICS</A>
+<P>
+Exit status is 0 if any matches were found, 1 if no matches were found, and 2
+for syntax errors or inacessible files (even if matches were found).
+</P>
+<LI><A NAME="SEC7" HREF="#TOC1">AUTHOR</A>
+<P>
+Philip Hazel &#60;ph10@cam.ac.uk&#62;
+<BR>
+Copyright (c) 1997-1999 University of Cambridge.
diff --git a/ext/pcre/pcrelib/doc/pgrep.txt b/ext/pcre/pcrelib/doc/pgrep.txt
new file mode 100644 (file)
index 0000000..bcd08c0
--- /dev/null
@@ -0,0 +1,86 @@
+NAME
+     pgrep - a grep with Perl-compatible regular expressions.
+
+
+
+SYNOPSIS
+     pgrep [-Vchilnsvx] pattern [file] ...
+
+
+
+DESCRIPTION
+     pgrep searches files for character patterns, in the same way
+     as  other  grep  commands  do,  but it uses the PCRE regular
+     expression library to support patterns that  are  compatible
+     with  the  regular  expressions of Perl 5. See pcre(3) for a
+     full description of syntax and semantics.
+
+     If no files are specified, pgrep reads the  standard  input.
+     By  default, each line that matches the pattern is copied to
+     the standard output, and if there is more than one file, the
+     file  name  is  printed before each line of output. However,
+     there are options that can change how pgrep behaves.
+
+     Lines are limited to BUFSIZ characters. BUFSIZ is defined in
+     <stdio.h>.  The newline character is removed from the end of
+     each line before it is matched against the pattern.
+
+
+
+OPTIONS
+     -V        Write the version number of the PCRE library being
+               used to the standard error stream.
+
+     -c        Do not print individual lines; instead just  print
+               a  count  of the number of lines that would other-
+               wise have  been  printed.  If  several  files  are
+               given, a count is printed for each of them.
+
+     -h        Suppress printing of filenames when searching mul-
+               tiple files.
+
+     -i        Ignore upper/lower case distinctions  during  com-
+               parisons.
+
+     -l        Instead of printing lines  from  the  files,  just
+               print the names of the files containing lines that
+               would have been printed. Each file name is printed
+               once, on a separate line.
+
+     -n        Precede each line by its line number in the file.
+
+     -s        Work silently, that  is,  display  nothing  except
+               error messages.  The exit status indicates whether
+               any matches were found.
+
+     -v        Invert the sense of the match, so that lines which
+               do not match the pattern are now the ones that are
+               found.
+
+     -x        Force the pattern to be anchored  (it  must  start
+               matching  at  the  beginning  of  the line) and in
+               addition, require it to  match  the  entire  line.
+               This is equivalent to having ^ and $ characters at
+               the start and end of each  alternative  branch  in
+               the regular expression.
+
+
+
+SEE ALSO
+     pcre(3), Perl 5 documentation
+
+
+
+
+
+DIAGNOSTICS
+     Exit status is 0 if any matches were found, 1 if no  matches
+     were  found,  and  2  for syntax errors or inacessible files
+     (even if matches were found).
+
+
+
+AUTHOR
+     Philip Hazel <ph10@cam.ac.uk>
+     Copyright (c) 1997-1999 University of Cambridge.
+
diff --git a/ext/pcre/pcrelib/testdata/testinput1 b/ext/pcre/pcrelib/testdata/testinput1
new file mode 100644 (file)
index 0000000..2f56b15
--- /dev/null
@@ -0,0 +1,1902 @@
+/the quick brown fox/
+    the quick brown fox
+    The quick brown FOX
+    What do you know about the quick brown fox?
+    What do you know about THE QUICK BROWN FOX?
+
+/The quick brown fox/i
+    the quick brown fox
+    The quick brown FOX
+    What do you know about the quick brown fox?
+    What do you know about THE QUICK BROWN FOX?
+
+/abcd\t\n\r\f\a\e\071\x3b\$\\\?caxyz/
+    abcd\t\n\r\f\a\e9;\$\\?caxyz
+
+/a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/
+    abxyzpqrrrabbxyyyypqAzz
+    abxyzpqrrrabbxyyyypqAzz
+    aabxyzpqrrrabbxyyyypqAzz
+    aaabxyzpqrrrabbxyyyypqAzz
+    aaaabxyzpqrrrabbxyyyypqAzz
+    abcxyzpqrrrabbxyyyypqAzz
+    aabcxyzpqrrrabbxyyyypqAzz
+    aaabcxyzpqrrrabbxyyyypAzz
+    aaabcxyzpqrrrabbxyyyypqAzz
+    aaabcxyzpqrrrabbxyyyypqqAzz
+    aaabcxyzpqrrrabbxyyyypqqqAzz
+    aaabcxyzpqrrrabbxyyyypqqqqAzz
+    aaabcxyzpqrrrabbxyyyypqqqqqAzz
+    aaabcxyzpqrrrabbxyyyypqqqqqqAzz
+    aaaabcxyzpqrrrabbxyyyypqAzz
+    abxyzzpqrrrabbxyyyypqAzz
+    aabxyzzzpqrrrabbxyyyypqAzz
+    aaabxyzzzzpqrrrabbxyyyypqAzz
+    aaaabxyzzzzpqrrrabbxyyyypqAzz
+    abcxyzzpqrrrabbxyyyypqAzz
+    aabcxyzzzpqrrrabbxyyyypqAzz
+    aaabcxyzzzzpqrrrabbxyyyypqAzz
+    aaaabcxyzzzzpqrrrabbxyyyypqAzz
+    aaaabcxyzzzzpqrrrabbbxyyyypqAzz
+    aaaabcxyzzzzpqrrrabbbxyyyyypqAzz
+    aaabcxyzpqrrrabbxyyyypABzz
+    aaabcxyzpqrrrabbxyyyypABBzz
+    >>>aaabxyzpqrrrabbxyyyypqAzz
+    >aaaabxyzpqrrrabbxyyyypqAzz
+    >>>>abcxyzpqrrrabbxyyyypqAzz
+    *** Failers
+    abxyzpqrrabbxyyyypqAzz
+    abxyzpqrrrrabbxyyyypqAzz
+    abxyzpqrrrabxyyyypqAzz
+    aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz
+    aaaabcxyzzzzpqrrrabbbxyyypqAzz
+    aaabcxyzpqrrrabbxyyyypqqqqqqqAzz
+
+/^(abc){1,2}zz/
+    abczz
+    abcabczz
+    *** Failers
+    zz
+    abcabcabczz
+    >>abczz
+
+/^(b+?|a){1,2}?c/
+    bc
+    bbc
+    bbbc
+    bac
+    bbac
+    aac
+    abbbbbbbbbbbc
+    bbbbbbbbbbbac
+    *** Failers
+    aaac
+    abbbbbbbbbbbac
+
+/^(b+|a){1,2}c/
+    bc
+    bbc
+    bbbc
+    bac
+    bbac
+    aac
+    abbbbbbbbbbbc
+    bbbbbbbbbbbac
+    *** Failers
+    aaac
+    abbbbbbbbbbbac
+
+/^(b+|a){1,2}?bc/
+    bbc
+
+/^(b*|ba){1,2}?bc/
+    babc
+    bbabc
+    bababc
+    *** Failers
+    bababbc
+    babababc
+
+/^(ba|b*){1,2}?bc/
+    babc
+    bbabc
+    bababc
+    *** Failers
+    bababbc
+    babababc
+
+/^\ca\cA\c[\c{\c:/
+    \x01\x01\e;z
+
+/^[ab\]cde]/
+    athing
+    bthing
+    ]thing
+    cthing
+    dthing
+    ething
+    *** Failers
+    fthing
+    [thing
+    \\thing
+
+/^[]cde]/
+    ]thing
+    cthing
+    dthing
+    ething
+    *** Failers
+    athing
+    fthing
+
+/^[^ab\]cde]/
+    fthing
+    [thing
+    \\thing
+    *** Failers
+    athing
+    bthing
+    ]thing
+    cthing
+    dthing
+    ething
+
+/^[^]cde]/
+    athing
+    fthing
+    *** Failers
+    ]thing
+    cthing
+    dthing
+    ething
+
+/^\\81/
+    \81
+
+/^ÿ/
+    ÿ
+
+/^[0-9]+$/
+    0
+    1
+    2
+    3
+    4
+    5
+    6
+    7
+    8
+    9
+    10
+    100
+    *** Failers
+    abc
+
+/^.*nter/
+    enter
+    inter
+    uponter
+
+/^xxx[0-9]+$/
+    xxx0
+    xxx1234
+    *** Failers
+    xxx
+
+/^.+[0-9][0-9][0-9]$/
+    x123
+    xx123
+    123456
+    *** Failers
+    123
+    x1234
+
+/^.+?[0-9][0-9][0-9]$/
+    x123
+    xx123
+    123456
+    *** Failers
+    123
+    x1234
+
+/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/
+    abc!pqr=apquxz.ixr.zzz.ac.uk
+    *** Failers
+    !pqr=apquxz.ixr.zzz.ac.uk
+    abc!=apquxz.ixr.zzz.ac.uk
+    abc!pqr=apquxz:ixr.zzz.ac.uk
+    abc!pqr=apquxz.ixr.zzz.ac.ukk
+
+/:/
+    Well, we need a colon: somewhere
+    *** Fail if we don't
+
+/([\da-f:]+)$/i
+    0abc
+    abc
+    fed
+    E
+    ::
+    5f03:12C0::932e
+    fed def
+    Any old stuff
+    *** Failers
+    0zzz
+    gzzz
+    fed\x20
+    Any old rubbish
+
+/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
+    .1.2.3
+    A.12.123.0
+    *** Failers
+    .1.2.3333
+    1.2.3
+    1234.2.3
+
+/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/
+    1 IN SOA non-sp1 non-sp2(
+    1    IN    SOA    non-sp1    non-sp2   (
+    *** Failers
+    1IN SOA non-sp1 non-sp2(
+
+/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/
+    a.
+    Z.
+    2.
+    ab-c.pq-r.
+    sxk.zzz.ac.uk.
+    x-.y-.
+    *** Failers
+    -abc.peq.
+
+/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/
+    *.a
+    *.b0-a
+    *.c3-b.c
+    *.c-a.b-c
+    *** Failers
+    *.0
+    *.a-
+    *.a-b.c-
+    *.c-a.0-c
+
+/^(?=ab(de))(abd)(e)/
+    abde
+
+/^(?!(ab)de|x)(abd)(f)/
+    abdf
+
+/^(?=(ab(cd)))(ab)/
+    abcd
+
+/^[\da-f](\.[\da-f])*$/i
+    a.b.c.d
+    A.B.C.D
+    a.b.c.1.2.3.C
+
+/^\".*\"\s*(;.*)?$/
+    \"1234\"
+    \"abcd\" ;
+    \"\" ; rhubarb
+    *** Failers
+    \"1234\" : things
+
+/^$/
+    \
+    *** Failers
+
+/   ^    a   (?# begins with a)  b\sc (?# then b c) $ (?# then end)/x
+    ab c
+    *** Failers
+    abc
+    ab cde
+
+/(?x)   ^    a   (?# begins with a)  b\sc (?# then b c) $ (?# then end)/
+    ab c
+    *** Failers
+    abc
+    ab cde
+
+/^   a\ b[c ]d       $/x
+    a bcd
+    a b d
+    *** Failers
+    abcd
+    ab d
+
+/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/
+    abcdefhijklm
+
+/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/
+    abcdefhijklm
+
+/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/
+    a+ Z0+\x08\n\x1d\x12
+
+/^[.^$|()*+?{,}]+/
+    .^\$(*+)|{?,?}
+
+/^a*\w/
+    z
+    az
+    aaaz
+    a
+    aa
+    aaaa
+    a+
+    aa+
+
+/^a*?\w/
+    z
+    az
+    aaaz
+    a
+    aa
+    aaaa
+    a+
+    aa+
+
+/^a+\w/
+    az
+    aaaz
+    aa
+    aaaa
+    aa+
+
+/^a+?\w/
+    az
+    aaaz
+    aa
+    aaaa
+    aa+
+
+/^\d{8}\w{2,}/
+    1234567890
+    12345678ab
+    12345678__
+    *** Failers
+    1234567
+
+/^[aeiou\d]{4,5}$/
+    uoie
+    1234
+    12345
+    aaaaa
+    *** Failers
+    123456
+
+/^[aeiou\d]{4,5}?/
+    uoie
+    1234
+    12345
+    aaaaa
+    123456
+
+/\A(abc|def)=(\1){2,3}\Z/
+    abc=abcabc
+    def=defdefdef
+    *** Failers
+    abc=defdef
+
+/^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/
+    abcdefghijkcda2
+    abcdefghijkkkkcda2
+
+/(cat(a(ract|tonic)|erpillar)) \1()2(3)/
+    cataract cataract23
+    catatonic catatonic23
+    caterpillar caterpillar23
+
+
+/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/
+    From abcd  Mon Sep 01 12:33:02 1997
+
+/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/
+    From abcd  Mon Sep 01 12:33:02 1997
+    From abcd  Mon Sep  1 12:33:02 1997
+    *** Failers
+    From abcd  Sep 01 12:33:02 1997
+
+/^12.34/s
+    12\n34
+    12\r34
+
+/\w+(?=\t)/
+    the quick brown\t fox
+
+/foo(?!bar)(.*)/
+    foobar is foolish see?
+
+/(?:(?!foo)...|^.{0,2})bar(.*)/
+    foobar crowbar etc
+    barrel
+    2barrel
+    A barrel
+
+/^(\D*)(?=\d)(?!123)/
+    abc456
+    *** Failers
+    abc123
+
+/^1234(?# test newlines
+  inside)/
+    1234
+
+/^1234 #comment in extended re
+  /x
+    1234
+
+/#rhubarb
+  abcd/x
+    abcd
+
+/^abcd#rhubarb/x
+    abcd
+
+/^(a)\1{2,3}(.)/
+    aaab
+    aaaab
+    aaaaab
+    aaaaaab
+
+/(?!^)abc/
+    the abc
+    *** Failers
+    abc
+
+/(?=^)abc/
+    abc
+    *** Failers
+    the abc
+
+/^[ab]{1,3}(ab*|b)/
+    aabbbbb
+
+/^[ab]{1,3}?(ab*|b)/
+    aabbbbb
+
+/^[ab]{1,3}?(ab*?|b)/
+    aabbbbb
+
+/^[ab]{1,3}(ab*?|b)/
+    aabbbbb
+
+/  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*                          # optional leading comment
+(?:    (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?:                      # opening quote...
+[^\\\x80-\xff\n\015"]                #   Anything except backslash and quote
+|                     #    or
+\\ [^\x80-\xff]           #   Escaped something (something != CR)
+)* "  # closing quote
+)                    # initial word
+(?:  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  \.  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*   (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?:                      # opening quote...
+[^\\\x80-\xff\n\015"]                #   Anything except backslash and quote
+|                     #    or
+\\ [^\x80-\xff]           #   Escaped something (something != CR)
+)* "  # closing quote
+)  )* # further okay, if led by a period
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  @  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*    (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                           # initial subdomain
+(?:                                  #
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  \.                        # if led by a period...
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*   (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                     #   ...further okay
+)*
+# address
+|                     #  or
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?:                      # opening quote...
+[^\\\x80-\xff\n\015"]                #   Anything except backslash and quote
+|                     #    or
+\\ [^\x80-\xff]           #   Escaped something (something != CR)
+)* "  # closing quote
+)             # one word, optionally followed by....
+(?:
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037]  |  # atom and space parts, or...
+\(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)       |  # comments, or...
+
+" (?:                      # opening quote...
+[^\\\x80-\xff\n\015"]                #   Anything except backslash and quote
+|                     #    or
+\\ [^\x80-\xff]           #   Escaped something (something != CR)
+)* "  # closing quote
+# quoted strings
+)*
+<  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*                     # leading <
+(?:  @  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*    (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                           # initial subdomain
+(?:                                  #
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  \.                        # if led by a period...
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*   (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                     #   ...further okay
+)*
+
+(?:  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  ,  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  @  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*    (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                           # initial subdomain
+(?:                                  #
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  \.                        # if led by a period...
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*   (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                     #   ...further okay
+)*
+)* # further okay, if led by comma
+:                                # closing colon
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  )? #       optional route
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?:                      # opening quote...
+[^\\\x80-\xff\n\015"]                #   Anything except backslash and quote
+|                     #    or
+\\ [^\x80-\xff]           #   Escaped something (something != CR)
+)* "  # closing quote
+)                    # initial word
+(?:  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  \.  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*   (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?:                      # opening quote...
+[^\\\x80-\xff\n\015"]                #   Anything except backslash and quote
+|                     #    or
+\\ [^\x80-\xff]           #   Escaped something (something != CR)
+)* "  # closing quote
+)  )* # further okay, if led by a period
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  @  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*    (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                           # initial subdomain
+(?:                                  #
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  \.                        # if led by a period...
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*   (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                     #   ...further okay
+)*
+#       address spec
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  > #                  trailing >
+# name and address
+)  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*                       # optional trailing comment
+/x
+    Alan Other <user\@dom.ain>
+    <user\@dom.ain>
+    user\@dom.ain
+    \"A. Other\" <user.1234\@dom.ain> (a comment)
+    A. Other <user.1234\@dom.ain> (a comment)
+    \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay
+    A missing angle <user\@some.where
+    *** Failers
+    The quick brown fox
+
+/[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional leading comment
+(?:
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+|                       #  or
+"                                     # "
+[^\\\x80-\xff\n\015"] *                            #   normal
+(?:  \\ [^\x80-\xff]  [^\\\x80-\xff\n\015"] * )*        #   ( special normal* )*
+"                                     #        "
+# Quoted string
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+\.
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+|                       #  or
+"                                     # "
+[^\\\x80-\xff\n\015"] *                            #   normal
+(?:  \\ [^\x80-\xff]  [^\\\x80-\xff\n\015"] * )*        #   ( special normal* )*
+"                                     #        "
+# Quoted string
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# additional words
+)*
+@
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+)*
+# address
+|                             #  or
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+|                       #  or
+"                                     # "
+[^\\\x80-\xff\n\015"] *                            #   normal
+(?:  \\ [^\x80-\xff]  [^\\\x80-\xff\n\015"] * )*        #   ( special normal* )*
+"                                     #        "
+# Quoted string
+)
+# leading word
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] *               # "normal" atoms and or spaces
+(?:
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+|
+"                                     # "
+[^\\\x80-\xff\n\015"] *                            #   normal
+(?:  \\ [^\x80-\xff]  [^\\\x80-\xff\n\015"] * )*        #   ( special normal* )*
+"                                     #        "
+) # "special" comment or quoted string
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] *            #  more "normal"
+)*
+<
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# <
+(?:
+@
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+)*
+(?: ,
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+@
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+)*
+)*  # additional domains
+:
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+)?     #       optional route
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+|                       #  or
+"                                     # "
+[^\\\x80-\xff\n\015"] *                            #   normal
+(?:  \\ [^\x80-\xff]  [^\\\x80-\xff\n\015"] * )*        #   ( special normal* )*
+"                                     #        "
+# Quoted string
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+\.
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+|                       #  or
+"                                     # "
+[^\\\x80-\xff\n\015"] *                            #   normal
+(?:  \\ [^\x80-\xff]  [^\\\x80-\xff\n\015"] * )*        #   ( special normal* )*
+"                                     #        "
+# Quoted string
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# additional words
+)*
+@
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+)*
+#       address spec
+>                    #                 >
+# name and address
+)
+/x
+    Alan Other <user\@dom.ain>
+    <user\@dom.ain>
+    user\@dom.ain
+    \"A. Other\" <user.1234\@dom.ain> (a comment)
+    A. Other <user.1234\@dom.ain> (a comment)
+    \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay
+    A missing angle <user\@some.where
+    *** Failers
+    The quick brown fox
+
+/abc\0def\00pqr\000xyz\0000AB/
+    abc\0def\00pqr\000xyz\0000AB
+    abc456 abc\0def\00pqr\000xyz\0000ABCDE
+
+/abc\x0def\x00pqr\x000xyz\x0000AB/
+    abc\x0def\x00pqr\x000xyz\x0000AB
+    abc456 abc\x0def\x00pqr\x000xyz\x0000ABCDE
+
+/^[\000-\037]/
+    \0A
+    \01B
+    \037C
+
+/\0*/
+    \0\0\0\0
+
+/A\x0{2,3}Z/
+    The A\x0\x0Z
+    An A\0\x0\0Z
+    *** Failers
+    A\0Z
+    A\0\x0\0\x0Z
+
+/^(cow|)\1(bell)/
+    cowcowbell
+    bell
+    *** Failers
+    cowbell
+
+/^\s/
+    \040abc
+    \x0cabc
+    \nabc
+    \rabc
+    \tabc
+    *** Failers
+    abc
+
+/^a    b
+  
+  \f  c/x
+    abc
+
+/^(a|)\1*b/
+    ab
+    aaaab
+    b
+    *** Failers
+    acb
+
+/^(a|)\1+b/
+    aab
+    aaaab
+    b
+    *** Failers
+    ab
+
+/^(a|)\1?b/
+    ab
+    aab
+    b
+    *** Failers
+    acb
+
+/^(a|)\1{2}b/
+    aaab
+    b
+    *** Failers
+    ab
+    aab
+    aaaab
+
+/^(a|)\1{2,3}b/
+    aaab
+    aaaab
+    b
+    *** Failers
+    ab
+    aab
+    aaaaab
+
+/ab{1,3}bc/
+    abbbbc
+    abbbc
+    abbc
+    *** Failers
+    abc
+    abbbbbc
+
+/([^.]*)\.([^:]*):[T ]+(.*)/
+    track1.title:TBlah blah blah
+
+/([^.]*)\.([^:]*):[T ]+(.*)/i
+    track1.title:TBlah blah blah
+
+/([^.]*)\.([^:]*):[t ]+(.*)/i
+    track1.title:TBlah blah blah
+
+/^[W-c]+$/
+    WXY_^abc
+    ***Failers
+    wxy
+
+/^[W-c]+$/i
+    WXY_^abc
+    wxy_^ABC
+
+/^[\x3f-\x5F]+$/i
+    WXY_^abc
+    wxy_^ABC
+
+/^abc$/m
+    abc
+    qqq\nabc
+    abc\nzzz
+    qqq\nabc\nzzz
+
+/^abc$/
+    abc
+    *** Failers
+    qqq\nabc
+    abc\nzzz
+    qqq\nabc\nzzz
+
+/\Aabc\Z/m
+    abc
+    abc\n 
+    *** Failers
+    qqq\nabc
+    abc\nzzz
+    qqq\nabc\nzzz
+    
+/\A(.)*\Z/s
+    abc\ndef
+
+/\A(.)*\Z/m
+    *** Failers
+    abc\ndef
+
+/(?:b)|(?::+)/
+    b::c
+    c::b
+
+/[-az]+/
+    az-
+    *** Failers
+    b
+
+/[az-]+/
+    za-
+    *** Failers
+    b
+
+/[a\-z]+/
+    a-z
+    *** Failers
+    b
+
+/[a-z]+/
+    abcdxyz
+
+/[\d-]+/
+    12-34
+    *** Failers
+    aaa
+
+/[\d-z]+/
+    12-34z
+    *** Failers
+    aaa
+
+/\x5c/
+    \\
+
+/\x20Z/
+    the Zoo
+    *** Failers
+    Zulu
+
+/(abc)\1/i
+    abcabc
+    ABCabc
+    abcABC
+
+/(main(O)?)+/
+    mainmain
+    mainOmain
+
+/ab{3cd/
+    ab{3cd
+
+/ab{3,cd/
+    ab{3,cd
+
+/ab{3,4a}cd/
+    ab{3,4a}cd
+
+/{4,5a}bc/
+    {4,5a}bc
+
+/^a.b/
+    a\rb
+    *** Failers
+    a\nb
+
+/abc$/
+    abc
+    abc\n
+    *** Failers
+    abc\ndef
+
+/(abc)\123/
+    abc\x53
+
+/(abc)\223/
+    abc\x93
+
+/(abc)\323/
+    abc\xd3
+
+/(abc)\500/
+    abc\x40
+    abc\100
+
+/(abc)\5000/
+    abc\x400
+    abc\x40\x30
+    abc\1000
+    abc\100\x30
+    abc\100\060
+    abc\100\60
+
+/abc\81/
+    abc\081
+    abc\0\x38\x31
+
+/abc\91/
+    abc\091
+    abc\0\x39\x31
+
+/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\12\123/
+    abcdefghijkllS
+
+/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/
+    abcdefghijk\12S
+
+/ab\gdef/
+    abgdef
+
+/a{0}bc/
+    bc
+
+/(a|(bc)){0,0}?xyz/
+    xyz
+
+/abc[\10]de/
+    abc\010de
+
+/abc[\1]de/
+    abc\1de
+
+/(abc)[\1]de/
+    abc\1de
+
+/a.b(?s)/
+    a\nb
+
+/^([^a])([^\b])([^c]*)([^d]{3,4})/
+    baNOTccccd
+    baNOTcccd
+    baNOTccd
+    bacccd
+    *** Failers
+    anything
+    b\bc   
+    baccd
+
+/[^a]/
+    Abc
+  
+/[^a]/i
+    Abc 
+
+/[^a]+/
+    AAAaAbc
+  
+/[^a]+/i
+    AAAaAbc 
+
+/[^a]+/
+    bbb\nccc
+   
+/[^k]$/
+    abc
+    *** Failers
+    abk   
+   
+/[^k]{2,3}$/
+    abc
+    kbc
+    kabc 
+    *** Failers
+    abk
+    akb
+    akk 
+
+/^\d{8,}\@.+[^k]$/
+    12345678\@a.b.c.d
+    123456789\@x.y.z
+    *** Failers
+    12345678\@x.y.uk
+    1234567\@a.b.c.d       
+
+/(a)\1{8,}/
+    aaaaaaaaa
+    aaaaaaaaaa
+    *** Failers
+    aaaaaaa   
+
+/[^a]/
+    aaaabcd
+    aaAabcd 
+
+/[^a]/i
+    aaaabcd
+    aaAabcd 
+
+/[^az]/
+    aaaabcd
+    aaAabcd 
+
+/[^az]/i
+    aaaabcd
+    aaAabcd 
+
+/\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377/
+ \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377
+
+/P[^*]TAIRE[^*]{1,6}?LL/
+    xxxxxxxxxxxPSTAIREISLLxxxxxxxxx
+
+/P[^*]TAIRE[^*]{1,}?LL/
+    xxxxxxxxxxxPSTAIREISLLxxxxxxxxx
+
+/(\.\d\d[1-9]?)\d+/
+    1.230003938
+    1.875000282   
+    1.235  
+                  
+/(\.\d\d((?=0)|\d(?=\d)))/
+    1.230003938      
+    1.875000282
+    *** Failers 
+    1.235 
+    
+/a(?)b/
+    ab 
+/\b(foo)\s+(\w+)/i
+    Food is on the foo table
+    
+/foo(.*)bar/
+    The food is under the bar in the barn.
+    
+/foo(.*?)bar/  
+    The food is under the bar in the barn.
+
+/(.*)(\d*)/
+    I have 2 numbers: 53147
+    
+/(.*)(\d+)/
+    I have 2 numbers: 53147
+/(.*?)(\d*)/
+    I have 2 numbers: 53147
+
+/(.*?)(\d+)/
+    I have 2 numbers: 53147
+
+/(.*)(\d+)$/
+    I have 2 numbers: 53147
+
+/(.*?)(\d+)$/
+    I have 2 numbers: 53147
+
+/(.*)\b(\d+)$/
+    I have 2 numbers: 53147
+
+/(.*\D)(\d+)$/
+    I have 2 numbers: 53147
+
+/^\D*(?!123)/
+    ABC123
+     
+/^(\D*)(?=\d)(?!123)/
+    ABC445
+    *** Failers
+    ABC123
+    
+/^[W-]46]/
+    W46]789 
+    -46]789
+    *** Failers
+    Wall
+    Zebra
+    42
+    [abcd] 
+    ]abcd[
+       
+/^[W-\]46]/
+    W46]789 
+    Wall
+    Zebra
+    Xylophone  
+    42
+    [abcd] 
+    ]abcd[
+    \\backslash 
+    *** Failers
+    -46]789
+    well
+    
+/\d\d\/\d\d\/\d\d\d\d/
+    01/01/2000
+
+/word (?:[a-zA-Z0-9]+ ){0,10}otherword/
+  word cat dog elephant mussel cow horse canary baboon snake shark otherword
+  word cat dog elephant mussel cow horse canary baboon snake shark
+
+/word (?:[a-zA-Z0-9]+ ){0,300}otherword/
+  word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope
+
+/^(a){0,0}/
+    bcd
+    abc
+    aab     
+
+/^(a){0,1}/
+    bcd
+    abc
+    aab  
+
+/^(a){0,2}/
+    bcd
+    abc
+    aab  
+
+/^(a){0,3}/
+    bcd
+    abc
+    aab
+    aaa   
+
+/^(a){0,}/
+    bcd
+    abc
+    aab
+    aaa
+    aaaaaaaa    
+
+/^(a){1,1}/
+    bcd
+    abc
+    aab  
+
+/^(a){1,2}/
+    bcd
+    abc
+    aab  
+
+/^(a){1,3}/
+    bcd
+    abc
+    aab
+    aaa   
+
+/^(a){1,}/
+    bcd
+    abc
+    aab
+    aaa
+    aaaaaaaa    
+
+/.*\.gif/
+    borfle\nbib.gif\nno
+
+/.{0,}\.gif/
+    borfle\nbib.gif\nno
+
+/.*\.gif/m
+    borfle\nbib.gif\nno
+
+/.*\.gif/s
+    borfle\nbib.gif\nno
+
+/.*\.gif/ms
+    borfle\nbib.gif\nno
+    
+/.*$/
+    borfle\nbib.gif\nno
+
+/.*$/m
+    borfle\nbib.gif\nno
+
+/.*$/s
+    borfle\nbib.gif\nno
+
+/.*$/ms
+    borfle\nbib.gif\nno
+    
+/.*$/
+    borfle\nbib.gif\nno\n
+
+/.*$/m
+    borfle\nbib.gif\nno\n
+
+/.*$/s
+    borfle\nbib.gif\nno\n
+
+/.*$/ms
+    borfle\nbib.gif\nno\n
+    
+/(.*X|^B)/
+    abcde\n1234Xyz
+    BarFoo 
+    *** Failers
+    abcde\nBar  
+
+/(.*X|^B)/m
+    abcde\n1234Xyz
+    BarFoo 
+    abcde\nBar  
+
+/(.*X|^B)/s
+    abcde\n1234Xyz
+    BarFoo 
+    *** Failers
+    abcde\nBar  
+
+/(.*X|^B)/ms
+    abcde\n1234Xyz
+    BarFoo 
+    abcde\nBar  
+
+/(?s)(.*X|^B)/
+    abcde\n1234Xyz
+    BarFoo 
+    *** Failers 
+    abcde\nBar  
+
+/(?s:.*X|^B)/
+    abcde\n1234Xyz
+    BarFoo 
+    *** Failers 
+    abcde\nBar  
+
+/^.*B/
+    **** Failers
+    abc\nB
+     
+/(?s)^.*B/
+    abc\nB
+
+/(?m)^.*B/
+    abc\nB
+     
+/(?ms)^.*B/
+    abc\nB
+
+/(?ms)^B/
+    abc\nB
+
+/(?s)B$/
+    B\n
+
+/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/
+    123456654321
+  
+/^\d\d\d\d\d\d\d\d\d\d\d\d/
+    123456654321 
+
+/^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/
+    123456654321
+  
+/^[abc]{12}/
+    abcabcabcabc
+    
+/^[a-c]{12}/
+    abcabcabcabc
+    
+/^(a|b|c){12}/
+    abcabcabcabc 
+
+/^[abcdefghijklmnopqrstuvwxy0123456789]/
+    n
+    *** Failers 
+    z 
+
+/abcde{0,0}/
+    abcd
+    *** Failers
+    abce  
+
+/ab[cd]{0,0}e/
+    abe
+    *** Failers
+    abcde 
+    
+/ab(c){0,0}d/
+    abd
+    *** Failers
+    abcd   
+
+/a(b*)/
+    a
+    ab
+    abbbb
+    *** Failers
+    bbbbb    
+    
+/ab\d{0}e/
+    abe
+    *** Failers
+    ab1e   
+    
+/"([^\\"]+|\\.)*"/
+    the \"quick\" brown fox
+    \"the \\\"quick\\\" brown fox\" 
+
+/.*?/g+
+    abc
+  
+/\b/g+
+    abc 
+
+/\b/+g
+    abc 
+
+//g
+    abc
+
+/ End of test input /
diff --git a/ext/pcre/pcrelib/testdata/testinput2 b/ext/pcre/pcrelib/testdata/testinput2
new file mode 100644 (file)
index 0000000..1d9504c
--- /dev/null
@@ -0,0 +1,710 @@
+/(a)b|/
+
+/abc/
+    abc
+    defabc
+    \Aabc
+    *** Failers
+    \Adefabc
+    ABC
+
+/^abc/
+    abc
+    \Aabc
+    *** Failers
+    defabc
+    \Adefabc
+
+/a+bc/
+
+/a*bc/
+
+/a{3}bc/
+
+/(abc|a+z)/
+
+/^abc$/
+    abc
+    *** Failers
+    def\nabc
+
+/ab\gdef/X
+
+/(?X)ab\gdef/X
+
+/x{5,4}/
+
+/z{65536}/
+
+/[abcd/
+
+/[\B]/
+
+/[a-\w]/
+
+/[z-a]/
+
+/^*/
+
+/(abc/
+
+/(?# abc/
+
+/(?z)abc/
+
+/.*b/
+
+/.*?b/
+
+/cat|dog|elephant/
+    this sentence eventually mentions a cat
+    this sentences rambles on and on for a while and then reaches elephant
+
+/cat|dog|elephant/S
+    this sentence eventually mentions a cat
+    this sentences rambles on and on for a while and then reaches elephant
+
+/cat|dog|elephant/iS
+    this sentence eventually mentions a CAT cat
+    this sentences rambles on and on for a while to elephant ElePhant
+
+/a|[bcd]/S
+
+/(a|[^\dZ])/S
+
+/(a|b)*[\s]/S
+
+/(ab\2)/
+
+/{4,5}abc/
+
+/(a)(b)(c)\2/
+    abcb
+    \O0abcb
+    \O3abcb
+    \O6abcb
+    \O9abcb
+    \O12abcb 
+
+/(a)bc|(a)(b)\2/
+    abc
+    \O0abc
+    \O3abc
+    \O6abc
+    aba
+    \O0aba
+    \O3aba
+    \O6aba
+    \O9aba
+    \O12aba
+
+/abc$/E
+    abc
+    *** Failers
+    abc\n
+    abc\ndef
+
+/(a)(b)(c)(d)(e)\6/
+
+/the quick brown fox/
+    the quick brown fox
+    this is a line with the quick brown fox
+
+/the quick brown fox/A
+    the quick brown fox
+    *** Failers
+    this is a line with the quick brown fox
+
+/ab(?z)cd/
+
+/^abc|def/
+    abcdef
+    abcdef\B
+
+/.*((abc)$|(def))/
+    defabc
+    \Zdefabc
+
+/abc/P
+    abc
+    *** Failers
+    
+/^abc|def/P
+    abcdef
+    abcdef\B
+
+/.*((abc)$|(def))/P
+    defabc
+    \Zdefabc
+  
+/the quick brown fox/P
+    the quick brown fox
+    *** Failers 
+    The Quick Brown Fox 
+
+/the quick brown fox/Pi
+    the quick brown fox
+    The Quick Brown Fox 
+
+/abc.def/P
+    *** Failers
+    abc\ndef
+    
+/abc$/P
+    abc
+    abc\n 
+
+/(abc)\2/P
+
+/(abc\1)/P
+    abc
+
+/)/
+
+/a[]b/
+
+/[^aeiou ]{3,}/
+    co-processors, and for 
+    
+/<.*>/
+    abc<def>ghi<klm>nop
+
+/<.*?>/
+    abc<def>ghi<klm>nop
+
+/<.*>/U
+    abc<def>ghi<klm>nop
+    
+/<.*>(?U)/
+    abc<def>ghi<klm>nop
+
+/<.*?>/U
+    abc<def>ghi<klm>nop
+    
+/={3,}/U
+    abc========def
+    
+/(?U)={3,}?/
+    abc========def
+    
+/(?<!bar|cattle)foo/
+    foo
+    catfoo 
+    *** Failers
+    the barfoo
+    and cattlefoo   
+
+/(?<=a+)b/
+
+/(?<=aaa|b{0,3})b/
+
+/(?<!(foo)a\1)bar/
+
+/(?i)abc/
+
+/(a|(?m)a)/
+
+/(?i)^1234/
+
+/(^b|(?i)^d)/
+
+/(?s).*/
+
+/[abcd]/S
+
+/(?i)[abcd]/S
+
+/(?m)[xy]|(b|c)/S
+
+/(^a|^b)/m
+
+/(?i)(^a|^b)/m
+
+/(a)(?(1)a|b|c)/
+
+/(?(?=a)a|b|c)/
+
+/(?(1a)/
+
+/(?(?i))/
+
+/(?(abc))/
+
+/(?(?<ab))/
+
+/((?s)blah)\s+\1/
+
+/((?i)blah)\s+\1/
+
+/((?i)b)/DS
+
+/(a*b|(?i:c*(?-i)d))/S
+
+/a$/
+    a
+    a\n
+    *** Failers 
+    \Za
+    \Za\n   
+
+/a$/m
+    a
+    a\n
+    \Za\n   
+    *** Failers 
+    \Za
+    
+/\Aabc/m
+
+/^abc/m 
+
+/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/
+  aaaaabbbbbcccccdef
+
+/(?<=foo)[ab]/S
+
+/(?<!foo)(alpha|omega)/S
+
+/(?!alphabet)[ab]/S
+
+/(?<=foo\n)^bar/m
+
+/(?>^abc)/m
+    abc
+    def\nabc
+    *** Failers
+    defabc   
+
+/(?<=ab(c+)d)ef/
+
+/(?<=ab(?<=c+)d)ef/
+
+/(?<=ab(c|de)f)g/
+
+/The next three are in testinput2 because they have variable length branches/
+
+/(?<=bullock|donkey)-cart/
+    the bullock-cart
+    a donkey-cart race
+    *** Failers
+    cart
+    horse-and-cart    
+      
+/(?<=ab(?i)x|y|z)/
+
+/(?>.*)(?<=(abcd)|(xyz))/
+    alphabetabcd
+    endingxyz
+
+/(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ/
+    abxyZZ
+    abXyZZ
+    ZZZ
+    zZZ
+    bZZ
+    BZZ     
+    *** Failers
+    ZZ 
+    abXYZZ 
+    zzz
+    bzz  
+
+/(?<!(foo)a)bar/
+    bar
+    foobbar 
+    *** Failers
+    fooabar  
+
+/This one is here because Perl 5.005_02 doesn't fail it/
+
+/^(a)?(?(1)a|b)+$/
+    *** Failers
+    a 
+
+/This one is here because I think Perl 5.005_02 gets the setting of $1 wrong/
+
+/^(a\1?){4}$/
+    aaaaaa
+    
+/These are syntax tests from Perl 5.005/
+
+/a[b-a]/
+
+/a[]b/
+
+/a[/
+
+/*a/
+
+/(*)b/
+
+/abc)/
+
+/(abc/
+
+/a**/
+
+/)(/
+
+/\1/
+
+/\2/
+
+/(a)|\2/
+
+/a[b-a]/i
+
+/a[]b/i
+
+/a[/i
+
+/*a/i
+
+/(*)b/i
+
+/abc)/i
+
+/(abc/i
+
+/a**/i
+
+/)(/i
+
+/:(?:/
+
+/(?<%)b/
+
+/a(?{)b/
+
+/a(?{{})b/
+
+/a(?{}})b/
+
+/a(?{"{"})b/
+
+/a(?{"{"}})b/
+
+/(?(1?)a|b)/
+
+/(?(1)a|b|c)/
+
+/[a[:xyz:/
+
+/(?<=x+)y/
+
+/a{37,17}/
+
+/abc/\
+
+/abc/\P
+
+/abc/\i
+
+/(a)bc(d)/
+    abcd
+    abcd\C2
+    abcd\C5
+     
+/(.{20})/
+    abcdefghijklmnopqrstuvwxyz
+    abcdefghijklmnopqrstuvwxyz\C1
+    abcdefghijklmnopqrstuvwxyz\G1
+     
+/(.{15})/
+    abcdefghijklmnopqrstuvwxyz
+    abcdefghijklmnopqrstuvwxyz\C1\G1
+
+/(.{16})/
+    abcdefghijklmnopqrstuvwxyz
+    abcdefghijklmnopqrstuvwxyz\C1\G1\L
+    
+/^(a|(bc))de(f)/
+    adef\G1\G2\G3\G4\L 
+    bcdef\G1\G2\G3\G4\L 
+    adefghijk\C0 
+    
+/^abc\00def/
+    abc\00def\L\C0 
+    
+/word ((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ 
+)((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ 
+)?)?)?)?)?)?)?)?)?otherword/M
+
+/.*X/D
+
+/.*X/Ds
+
+/(.*X|^B)/D
+
+/(.*X|^B)/Ds
+    
+/(?s)(.*X|^B)/D
+
+/(?s:.*X|^B)/D
+
+/\Biss\B/+
+    Mississippi
+
+/\Biss\B/+P
+    Mississippi
+
+/iss/G+
+    Mississippi
+
+/\Biss\B/G+
+    Mississippi
+
+/\Biss\B/g+
+    Mississippi
+    *** Failers
+    Mississippi\A
+
+/(?<=[Ms])iss/g+
+    Mississippi
+
+/(?<=[Ms])iss/G+
+    Mississippi
+
+/^iss/g+
+    ississippi
+    
+/.*iss/g+
+    abciss\nxyzisspqr 
+
+/.i./+g
+    Mississippi
+    Mississippi\A
+    Missouri river
+    Missouri river\A  
+
+/^.is/+g
+    Mississippi
+
+/^ab\n/g+
+    ab\nab\ncd
+
+/^ab\n/mg+
+    ab\nab\ncd
+
+/abc/
+
+/abc|bac/
+
+/(abc|bac)/
+
+/(abc|(c|dc))/
+
+/(abc|(d|de)c)/
+
+/a*/
+
+/a+/
+
+/(baa|a+)/
+
+/a{0,3}/
+
+/baa{3,}/
+
+/"([^\\"]+|\\.)*"/
+
+/(abc|ab[cd])/
+
+/(a|.)/
+
+/a|ba|\w/
+
+/abc(?=pqr)/
+
+/...(?<=abc)/
+
+/abc(?!pqr)/
+
+/ab./
+
+/ab[xyz]/
+
+/abc*/
+
+/ab.c*/
+
+/a.c*/
+
+/.c*/
+
+/ac*/
+
+/(a.c*|b.c*)/
+
+/a.c*|aba/
+
+/.+a/
+
+/(?=abcda)a.*/
+
+/(?=a)a.*/
+
+/a(b)*/
+
+/a\d*/
+
+/ab\d*/
+
+/a(\d)*/
+
+/abcde{0,0}/
+
+/ab\d+/
+
+/a(?(1)b)/
+
+/a(?(1)bag|big)/
+
+/a(?(1)bag|big)*/
+
+/a(?(1)bag|big)+/
+
+/a(?(1)b..|b..)/
+
+/ab\d{0}e/
+
+/a?b?/
+    a
+    b
+    ab
+    \
+    *** Failers
+    \N     
+    
+/|-/
+    abcd
+    -abc
+    \Nab-c
+    *** Failers
+    \Nabc     
+
+/a*(b+)(z)(z)/P
+    aaaabbbbzzzz
+    aaaabbbbzzzz\O0
+    aaaabbbbzzzz\O1
+    aaaabbbbzzzz\O2
+    aaaabbbbzzzz\O3
+    aaaabbbbzzzz\O4
+    aaaabbbbzzzz\O5
+    
+/^.?abcd/S 
+
+/\(             # ( at start
+  (?:           # Non-capturing bracket
+  (?>[^()]+)    # Either a sequence of non-brackets (no backtracking)
+  |             # Or
+  (?R)          # Recurse - i.e. nested bracketed string
+  )*            # Zero or more contents
+  \)            # Closing )
+  /x
+    (abcd)
+    (abcd)xyz
+    xyz(abcd)
+    (ab(xy)cd)pqr 
+    (ab(xycd)pqr 
+    () abc () 
+    12(abcde(fsh)xyz(foo(bar))lmno)89
+    *** Failers
+    abcd 
+    abcd)
+    (abcd  
+
+/\(  ( (?>[^()]+) | (?R) )* \) /xg
+    (ab(xy)cd)pqr 
+    1(abcd)(x(y)z)pqr
+
+/\(  (?: (?>[^()]+) | (?R) ) \) /x
+    (abcd)
+    (ab(xy)cd)
+    (a(b(c)d)e) 
+    ((ab)) 
+    *** Failers
+    ()   
+
+/\(  (?: (?>[^()]+) | (?R) )? \) /x
+    ()
+    12(abcde(fsh)xyz(foo(bar))lmno)89
+
+/\(  ( (?>[^()]+) | (?R) )* \) /x
+    (ab(xy)cd)
+
+/\( ( ( (?>[^()]+) | (?R) )* ) \) /x
+    (ab(xy)cd)
+
+/\( (123)? ( ( (?>[^()]+) | (?R) )* ) \) /x
+    (ab(xy)cd)
+    (123ab(xy)cd)
+
+/\( ( (123)? ( (?>[^()]+) | (?R) )* ) \) /x
+    (ab(xy)cd)
+    (123ab(xy)cd)
+
+/\( (((((((((( ( (?>[^()]+) | (?R) )* )))))))))) \) /x
+    (ab(xy)cd)
+
+/\( ( ( (?>[^()<>]+) | ((?>[^()]+)) | (?R) )* ) \) /x
+    (abcd(xyz<p>qrs)123)
+
+/\( ( ( (?>[^()]+) | ((?R)) )* ) \) /x
+    (ab(cd)ef)
+    (ab(cd(ef)gh)ij)
+
+/^[[:alnum:]]/D
+
+/^[[:alpha:]]/D
+             
+/^[[:ascii:]]/D
+
+/^[[:cntrl:]]/D
+
+/^[[:digit:]]/D
+
+/^[[:graph:]]/D
+
+/^[[:lower:]]/D
+
+/^[[:print:]]/D
+
+/^[[:punct:]]/D
+
+/^[[:space:]]/D
+
+/^[[:upper:]]/D
+
+/^[[:xdigit:]]/D
+
+/^[[:word:]]/D
+
+/^[[:^cntrl:]]/D
+
+/^[12[:^digit:]]/D
+
+/[01[:alpha:]%]/D
+
+/[[.ch.]]/
+
+/[[=ch=]]/
+
+/[[:rhubarb:]]/
+
+/[[:upper:]]/i
+    A
+    a 
+    
+/[[:lower:]]/i
+    A
+    a 
+
+/((?-i)[[:lower:]])[[:lower:]]/i
+    ab
+    aB
+    *** Failers
+    Ab
+    AB        
+
+/ End of test input /
diff --git a/ext/pcre/pcrelib/testdata/testinput3 b/ext/pcre/pcrelib/testdata/testinput3
new file mode 100644 (file)
index 0000000..0c884d3
--- /dev/null
@@ -0,0 +1,1692 @@
+/(?<!bar)foo/
+    foo
+    catfood
+    arfootle
+    rfoosh
+    *** Failers
+    barfoo
+    towbarfoo
+
+/\w{3}(?<!bar)foo/
+    catfood
+    *** Failers
+    foo
+    barfoo
+    towbarfoo
+
+/(?<=(foo)a)bar/
+    fooabar
+    *** Failers
+    bar
+    foobbar
+      
+/\Aabc\z/m
+    abc
+    *** Failers
+    abc\n   
+    qqq\nabc
+    abc\nzzz
+    qqq\nabc\nzzz
+
+"(?>.*/)foo"
+    /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/
+
+"(?>.*/)foo"
+    /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo
+
+/(?>(\.\d\d[1-9]?))\d+/
+    1.230003938
+    1.875000282
+    *** Failers 
+    1.235 
+
+/^((?>\w+)|(?>\s+))*$/
+    now is the time for all good men to come to the aid of the party
+    *** Failers
+    this is not a line with only words and spaces!
+    
+/(\d+)(\w)/
+    12345a
+    12345+ 
+
+/((?>\d+))(\w)/
+    12345a
+    *** Failers
+    12345+ 
+
+/(?>a+)b/
+    aaab
+
+/((?>a+)b)/
+    aaab
+
+/(?>(a+))b/
+    aaab
+
+/(?>b)+/
+    aaabbbccc
+
+/(?>a+|b+|c+)*c/
+    aaabbbbccccd
+
+/((?>[^()]+)|\([^()]*\))+/
+    ((abc(ade)ufh()()x
+    
+/\(((?>[^()]+)|\([^()]+\))+\)/ 
+    (abc)
+    (abc(def)xyz)
+    *** Failers
+    ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa   
+
+/a(?-i)b/i
+    ab
+    *** Failers 
+    Ab
+    aB
+    AB
+        
+/(a (?x)b c)d e/
+    a bcd e
+    *** Failers
+    a b cd e
+    abcd e   
+    a bcde 
+/(a b(?x)c d (?-x)e f)/
+    a bcde f
+    *** Failers
+    abcdef  
+
+/(a(?i)b)c/
+    abc
+    aBc
+    *** Failers
+    abC
+    aBC  
+    Abc
+    ABc
+    ABC
+    AbC
+    
+/a(?i:b)c/
+    abc
+    aBc
+    *** Failers 
+    ABC
+    abC
+    aBC
+    
+/a(?i:b)*c/
+    aBc
+    aBBc
+    *** Failers 
+    aBC
+    aBBC
+    
+/a(?=b(?i)c)\w\wd/
+    abcd
+    abCd
+    *** Failers
+    aBCd
+    abcD     
+    
+/(?s-i:more.*than).*million/i
+    more than million
+    more than MILLION
+    more \n than Million 
+    *** Failers
+    MORE THAN MILLION    
+    more \n than \n million 
+
+/(?:(?s-i)more.*than).*million/i
+    more than million
+    more than MILLION
+    more \n than Million 
+    *** Failers
+    MORE THAN MILLION    
+    more \n than \n million 
+    
+/(?>a(?i)b+)+c/ 
+    abc
+    aBbc
+    aBBc 
+    *** Failers
+    Abc
+    abAb    
+    abbC 
+    
+/(?=a(?i)b)\w\wc/
+    abc
+    aBc
+    *** Failers
+    Ab 
+    abC
+    aBC     
+    
+/(?<=a(?i)b)(\w\w)c/
+    abxxc
+    aBxxc
+    *** Failers
+    Abxxc
+    ABxxc
+    abxxC      
+
+/(?:(a)|b)(?(1)A|B)/
+    aA
+    bB
+    *** Failers
+    aB
+    bA    
+
+/^(a)?(?(1)a|b)+$/
+    aa
+    b
+    bb  
+    *** Failers
+    ab   
+
+/^(?(?=abc)\w{3}:|\d\d)$/
+    abc:
+    12
+    *** Failers
+    123
+    xyz    
+
+/^(?(?!abc)\d\d|\w{3}:)$/
+    abc:
+    12
+    *** Failers
+    123
+    xyz    
+    
+/(?(?<=foo)bar|cat)/
+    foobar
+    cat
+    fcat
+    focat   
+    *** Failers
+    foocat  
+
+/(?(?<!foo)cat|bar)/
+    foobar
+    cat
+    fcat
+    focat   
+    *** Failers
+    foocat  
+
+/( \( )? [^()]+ (?(1) \) |) /x
+    abcd
+    (abcd)
+    the quick (abcd) fox
+    (abcd   
+
+/( \( )? [^()]+ (?(1) \) ) /x
+    abcd
+    (abcd)
+    the quick (abcd) fox
+    (abcd   
+
+/^(?(2)a|(1)(2))+$/
+    12
+    12a
+    12aa
+    *** Failers
+    1234    
+
+/((?i)blah)\s+\1/
+    blah blah
+    BLAH BLAH
+    Blah Blah
+    blaH blaH
+    *** Failers
+    blah BLAH
+    Blah blah      
+    blaH blah 
+
+/((?i)blah)\s+(?i:\1)/
+    blah blah
+    BLAH BLAH
+    Blah Blah
+    blaH blaH
+    blah BLAH
+    Blah blah      
+    blaH blah 
+
+/(?>a*)*/
+    a
+    aa
+    aaaa
+    
+/(abc|)+/
+    abc
+    abcabc
+    abcabcabc
+    xyz      
+
+/([a]*)*/
+    a
+    aaaaa 
+/([ab]*)*/
+    a
+    b
+    ababab
+    aaaabcde
+    bbbb    
+/([^a]*)*/
+    b
+    bbbb
+    aaa   
+/([^ab]*)*/
+    cccc
+    abab  
+/([a]*?)*/
+    a
+    aaaa 
+/([ab]*?)*/
+    a
+    b
+    abab
+    baba   
+/([^a]*?)*/
+    b
+    bbbb
+    aaa   
+/([^ab]*?)*/
+    c
+    cccc
+    baba   
+/(?>a*)*/
+    a
+    aaabcde 
+/((?>a*))*/
+    aaaaa
+    aabbaa 
+/((?>a*?))*/
+    aaaaa
+    aabbaa 
+
+/(?(?=[^a-z]+[a-z])  \d{2}-[a-z]{3}-\d{2}  |  \d{2}-\d{2}-\d{2} ) /x
+    12-sep-98
+    12-09-98
+    *** Failers
+    sep-12-98
+        
+/(?<=(foo))bar\1/
+    foobarfoo
+    foobarfootling 
+    *** Failers
+    foobar
+    barfoo   
+
+/(?i:saturday|sunday)/
+    saturday
+    sunday
+    Saturday
+    Sunday
+    SATURDAY
+    SUNDAY
+    SunDay
+    
+/(a(?i)bc|BB)x/
+    abcx
+    aBCx
+    bbx
+    BBx
+    *** Failers
+    abcX
+    aBCX
+    bbX
+    BBX               
+
+/^([ab](?i)[cd]|[ef])/
+    ac
+    aC
+    bD
+    elephant
+    Europe 
+    frog
+    France
+    *** Failers
+    Africa     
+
+/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/
+    ab
+    aBd
+    xy
+    xY
+    zebra
+    Zambesi
+    *** Failers
+    aCD  
+    XY  
+
+/(?<=foo\n)^bar/m
+    foo\nbar
+    *** Failers
+    bar
+    baz\nbar   
+
+/(?<=(?<!foo)bar)baz/
+    barbaz
+    barbarbaz 
+    koobarbaz 
+    *** Failers
+    baz
+    foobarbaz 
+
+/The case of aaaaaa is missed out below because I think Perl 5.005_02 gets/
+/it wrong; it sets $1 to aaa rather than aa. Compare the following test,/
+/where it does set $1 to aa when matching aaaaaa./
+
+/^(a\1?){4}$/
+    a
+    aa
+    aaa
+    aaaa
+    aaaaa
+    aaaaaaa
+    aaaaaaaa
+    aaaaaaaaa
+    aaaaaaaaaa
+    aaaaaaaaaaa
+    aaaaaaaaaaaa
+    aaaaaaaaaaaaa
+    aaaaaaaaaaaaaa
+    aaaaaaaaaaaaaaa
+    aaaaaaaaaaaaaaaa               
+
+/^(a\1?)(a\1?)(a\2?)(a\3?)$/
+    a
+    aa
+    aaa
+    aaaa
+    aaaaa
+    aaaaaa
+    aaaaaaa
+    aaaaaaaa
+    aaaaaaaaa
+    aaaaaaaaaa
+    aaaaaaaaaaa
+    aaaaaaaaaaaa
+    aaaaaaaaaaaaa
+    aaaaaaaaaaaaaa
+    aaaaaaaaaaaaaaa
+    aaaaaaaaaaaaaaaa               
+
+/The following tests are taken from the Perl 5.005 test suite; some of them/
+/are compatible with 5.004, but I'd rather not have to sort them out./
+
+/abc/
+    abc
+    xabcy
+    ababc
+    *** Failers
+    xbc
+    axc
+    abx
+
+/ab*c/
+    abc
+
+/ab*bc/
+    abc
+    abbc
+    abbbbc
+
+/.{1}/
+    abbbbc
+
+/.{3,4}/
+    abbbbc
+
+/ab{0,}bc/
+    abbbbc
+
+/ab+bc/
+    abbc
+    *** Failers
+    abc
+    abq
+
+/ab{1,}bc/
+
+/ab+bc/
+    abbbbc
+
+/ab{1,}bc/
+    abbbbc
+
+/ab{1,3}bc/
+    abbbbc
+
+/ab{3,4}bc/
+    abbbbc
+
+/ab{4,5}bc/
+    *** Failers
+    abq
+    abbbbc
+
+/ab?bc/
+    abbc
+    abc
+
+/ab{0,1}bc/
+    abc
+
+/ab?bc/
+
+/ab?c/
+    abc
+
+/ab{0,1}c/
+    abc
+
+/^abc$/
+    abc
+    *** Failers
+    abbbbc
+    abcc
+
+/^abc/
+    abcc
+
+/^abc$/
+
+/abc$/
+    aabc
+    *** Failers
+    aabc
+    aabcd
+
+/^/
+    abc
+
+/$/
+    abc
+
+/a.c/
+    abc
+    axc
+
+/a.*c/
+    axyzc
+
+/a[bc]d/
+    abd
+    *** Failers
+    axyzd
+    abc
+
+/a[b-d]e/
+    ace
+
+/a[b-d]/
+    aac
+
+/a[-b]/
+    a-
+
+/a[b-]/
+    a-
+
+/a]/
+    a]
+
+/a[]]b/
+    a]b
+
+/a[^bc]d/
+    aed
+    *** Failers
+    abd
+    abd
+
+/a[^-b]c/
+    adc
+
+/a[^]b]c/
+    adc
+    *** Failers
+    a-c
+    a]c
+
+/\ba\b/
+    a-
+    -a
+    -a-
+
+/\by\b/
+    *** Failers
+    xy
+    yz
+    xyz
+
+/\Ba\B/
+    *** Failers
+    a-
+    -a
+    -a-
+
+/\By\b/
+    xy
+
+/\by\B/
+    yz
+
+/\By\B/
+    xyz
+
+/\w/
+    a
+
+/\W/
+    -
+    *** Failers
+    -
+    a
+
+/a\sb/
+    a b
+
+/a\Sb/
+    a-b
+    *** Failers
+    a-b
+    a b
+
+/\d/
+    1
+
+/\D/
+    -
+    *** Failers
+    -
+    1
+
+/[\w]/
+    a
+
+/[\W]/
+    -
+    *** Failers
+    -
+    a
+
+/a[\s]b/
+    a b
+
+/a[\S]b/
+    a-b
+    *** Failers
+    a-b
+    a b
+
+/[\d]/
+    1
+
+/[\D]/
+    -
+    *** Failers
+    -
+    1
+
+/ab|cd/
+    abc
+    abcd
+
+/()ef/
+    def
+
+/$b/
+
+/a\(b/
+    a(b
+
+/a\(*b/
+    ab
+    a((b
+
+/a\\b/
+    a\b
+
+/((a))/
+    abc
+
+/(a)b(c)/
+    abc
+
+/a+b+c/
+    aabbabc
+
+/a{1,}b{1,}c/
+    aabbabc
+
+/a.+?c/
+    abcabc
+
+/(a+|b)*/
+    ab
+
+/(a+|b){0,}/
+    ab
+
+/(a+|b)+/
+    ab
+
+/(a+|b){1,}/
+    ab
+
+/(a+|b)?/
+    ab
+
+/(a+|b){0,1}/
+    ab
+
+/[^ab]*/
+    cde
+
+/abc/
+    *** Failers
+    b
+    
+
+/a*/
+    
+
+/([abc])*d/
+    abbbcd
+
+/([abc])*bcd/
+    abcd
+
+/a|b|c|d|e/
+    e
+
+/(a|b|c|d|e)f/
+    ef
+
+/abcd*efg/
+    abcdefg
+
+/ab*/
+    xabyabbbz
+    xayabbbz
+
+/(ab|cd)e/
+    abcde
+
+/[abhgefdc]ij/
+    hij
+
+/^(ab|cd)e/
+
+/(abc|)ef/
+    abcdef
+
+/(a|b)c*d/
+    abcd
+
+/(ab|ab*)bc/
+    abc
+
+/a([bc]*)c*/
+    abc
+
+/a([bc]*)(c*d)/
+    abcd
+
+/a([bc]+)(c*d)/
+    abcd
+
+/a([bc]*)(c+d)/
+    abcd
+
+/a[bcd]*dcdcde/
+    adcdcde
+
+/a[bcd]+dcdcde/
+    *** Failers
+    abcde
+    adcdcde
+
+/(ab|a)b*c/
+    abc
+
+/((a)(b)c)(d)/
+    abcd
+
+/[a-zA-Z_][a-zA-Z0-9_]*/
+    alpha
+
+/^a(bc+|b[eh])g|.h$/
+    abh
+
+/(bc+d$|ef*g.|h?i(j|k))/
+    effgz
+    ij
+    reffgz
+    *** Failers
+    effg
+    bcdd
+
+/((((((((((a))))))))))/
+    a
+
+/((((((((((a))))))))))\10/
+    aa
+
+/(((((((((a)))))))))/
+    a
+
+/multiple words of text/
+    *** Failers
+    aa
+    uh-uh
+
+/multiple words/
+    multiple words, yeah
+
+/(.*)c(.*)/
+    abcde
+
+/\((.*), (.*)\)/
+    (a, b)
+
+/[k]/
+
+/abcd/
+    abcd
+
+/a(bc)d/
+    abcd
+
+/a[-]?c/
+    ac
+
+/(abc)\1/
+    abcabc
+
+/([a-c]*)\1/
+    abcabc
+
+/(a)|\1/
+    a
+    *** Failers
+    ab
+    x
+
+/(([a-c])b*?\2)*/
+    ababbbcbc
+
+/(([a-c])b*?\2){3}/
+    ababbbcbc
+
+/((\3|b)\2(a)x)+/
+    aaaxabaxbaaxbbax
+
+/((\3|b)\2(a)){2,}/
+    bbaababbabaaaaabbaaaabba
+
+/abc/i
+    ABC
+    XABCY
+    ABABC
+    *** Failers
+    aaxabxbaxbbx
+    XBC
+    AXC
+    ABX
+
+/ab*c/i
+    ABC
+
+/ab*bc/i
+    ABC
+    ABBC
+
+/ab*?bc/i
+    ABBBBC
+
+/ab{0,}?bc/i
+    ABBBBC
+
+/ab+?bc/i
+    ABBC
+
+/ab+bc/i
+    *** Failers
+    ABC
+    ABQ
+
+/ab{1,}bc/i
+
+/ab+bc/i
+    ABBBBC
+
+/ab{1,}?bc/i
+    ABBBBC
+
+/ab{1,3}?bc/i
+    ABBBBC
+
+/ab{3,4}?bc/i
+    ABBBBC
+
+/ab{4,5}?bc/i
+    *** Failers
+    ABQ
+    ABBBBC
+
+/ab??bc/i
+    ABBC
+    ABC
+
+/ab{0,1}?bc/i
+    ABC
+
+/ab??bc/i
+
+/ab??c/i
+    ABC
+
+/ab{0,1}?c/i
+    ABC
+
+/^abc$/i
+    ABC
+    *** Failers
+    ABBBBC
+    ABCC
+
+/^abc/i
+    ABCC
+
+/^abc$/i
+
+/abc$/i
+    AABC
+
+/^/i
+    ABC
+
+/$/i
+    ABC
+
+/a.c/i
+    ABC
+    AXC
+
+/a.*?c/i
+    AXYZC
+
+/a.*c/i
+    *** Failers
+    AABC
+    AXYZD
+
+/a[bc]d/i
+    ABD
+
+/a[b-d]e/i
+    ACE
+    *** Failers
+    ABC
+    ABD
+
+/a[b-d]/i
+    AAC
+
+/a[-b]/i
+    A-
+
+/a[b-]/i
+    A-
+
+/a]/i
+    A]
+
+/a[]]b/i
+    A]B
+
+/a[^bc]d/i
+    AED
+
+/a[^-b]c/i
+    ADC
+    *** Failers
+    ABD
+    A-C
+
+/a[^]b]c/i
+    ADC
+
+/ab|cd/i
+    ABC
+    ABCD
+
+/()ef/i
+    DEF
+
+/$b/i
+    *** Failers
+    A]C
+    B
+
+/a\(b/i
+    A(B
+
+/a\(*b/i
+    AB
+    A((B
+
+/a\\b/i
+    A\B
+
+/((a))/i
+    ABC
+
+/(a)b(c)/i
+    ABC
+
+/a+b+c/i
+    AABBABC
+
+/a{1,}b{1,}c/i
+    AABBABC
+
+/a.+?c/i
+    ABCABC
+
+/a.*?c/i
+    ABCABC
+
+/a.{0,5}?c/i
+    ABCABC
+
+/(a+|b)*/i
+    AB
+
+/(a+|b){0,}/i
+    AB
+
+/(a+|b)+/i
+    AB
+
+/(a+|b){1,}/i
+    AB
+
+/(a+|b)?/i
+    AB
+
+/(a+|b){0,1}/i
+    AB
+
+/(a+|b){0,1}?/i
+    AB
+
+/[^ab]*/i
+    CDE
+
+/abc/i
+
+/a*/i
+    
+
+/([abc])*d/i
+    ABBBCD
+
+/([abc])*bcd/i
+    ABCD
+
+/a|b|c|d|e/i
+    E
+
+/(a|b|c|d|e)f/i
+    EF
+
+/abcd*efg/i
+    ABCDEFG
+
+/ab*/i
+    XABYABBBZ
+    XAYABBBZ
+
+/(ab|cd)e/i
+    ABCDE
+
+/[abhgefdc]ij/i
+    HIJ
+
+/^(ab|cd)e/i
+    ABCDE
+
+/(abc|)ef/i
+    ABCDEF
+
+/(a|b)c*d/i
+    ABCD
+
+/(ab|ab*)bc/i
+    ABC
+
+/a([bc]*)c*/i
+    ABC
+
+/a([bc]*)(c*d)/i
+    ABCD
+
+/a([bc]+)(c*d)/i
+    ABCD
+
+/a([bc]*)(c+d)/i
+    ABCD
+
+/a[bcd]*dcdcde/i
+    ADCDCDE
+
+/a[bcd]+dcdcde/i
+
+/(ab|a)b*c/i
+    ABC
+
+/((a)(b)c)(d)/i
+    ABCD
+
+/[a-zA-Z_][a-zA-Z0-9_]*/i
+    ALPHA
+
+/^a(bc+|b[eh])g|.h$/i
+    ABH
+
+/(bc+d$|ef*g.|h?i(j|k))/i
+    EFFGZ
+    IJ
+    REFFGZ
+    *** Failers
+    ADCDCDE
+    EFFG
+    BCDD
+
+/((((((((((a))))))))))/i
+    A
+
+/((((((((((a))))))))))\10/i
+    AA
+
+/(((((((((a)))))))))/i
+    A
+
+/(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))/i
+    A
+
+/(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))/i
+    C
+
+/multiple words of text/i
+    *** Failers
+    AA
+    UH-UH
+
+/multiple words/i
+    MULTIPLE WORDS, YEAH
+
+/(.*)c(.*)/i
+    ABCDE
+
+/\((.*), (.*)\)/i
+    (A, B)
+
+/[k]/i
+
+/abcd/i
+    ABCD
+
+/a(bc)d/i
+    ABCD
+
+/a[-]?c/i
+    AC
+
+/(abc)\1/i
+    ABCABC
+
+/([a-c]*)\1/i
+    ABCABC
+
+/a(?!b)./
+    abad
+
+/a(?=d)./
+    abad
+
+/a(?=c|d)./
+    abad
+
+/a(?:b|c|d)(.)/
+    ace
+
+/a(?:b|c|d)*(.)/
+    ace
+
+/a(?:b|c|d)+?(.)/
+    ace
+    acdbcdbe
+
+/a(?:b|c|d)+(.)/
+    acdbcdbe
+
+/a(?:b|c|d){2}(.)/
+    acdbcdbe
+
+/a(?:b|c|d){4,5}(.)/
+    acdbcdbe
+
+/a(?:b|c|d){4,5}?(.)/
+    acdbcdbe
+
+/((foo)|(bar))*/
+    foobar
+
+/a(?:b|c|d){6,7}(.)/
+    acdbcdbe
+
+/a(?:b|c|d){6,7}?(.)/
+    acdbcdbe
+
+/a(?:b|c|d){5,6}(.)/
+    acdbcdbe
+
+/a(?:b|c|d){5,6}?(.)/
+    acdbcdbe
+
+/a(?:b|c|d){5,7}(.)/
+    acdbcdbe
+
+/a(?:b|c|d){5,7}?(.)/
+    acdbcdbe
+
+/a(?:b|(c|e){1,2}?|d)+?(.)/
+    ace
+
+/^(.+)?B/
+    AB
+
+/^([^a-z])|(\^)$/
+    .
+
+/^[<>]&/
+    <&OUT
+
+/^(a\1?){4}$/
+    aaaaaaaaaa
+    *** Failers
+    AB
+    aaaaaaaaa
+    aaaaaaaaaaa
+
+/^(a(?(1)\1)){4}$/
+    aaaaaaaaaa
+    *** Failers
+    aaaaaaaaa
+    aaaaaaaaaaa
+
+/(?:(f)(o)(o)|(b)(a)(r))*/
+    foobar
+
+/(?<=a)b/
+    ab
+    *** Failers
+    cb
+    b
+
+/(?<!c)b/
+    ab
+    b
+    b
+
+/(?:..)*a/
+    aba
+
+/(?:..)*?a/
+    aba
+
+/^(?:b|a(?=(.)))*\1/
+    abc
+
+/^(){3,5}/
+    abc
+
+/^(a+)*ax/
+    aax
+
+/^((a|b)+)*ax/
+    aax
+
+/^((a|bc)+)*ax/
+    aax
+
+/(a|x)*ab/
+    cab
+
+/(a)*ab/
+    cab
+
+/(?:(?i)a)b/
+    ab
+
+/((?i)a)b/
+    ab
+
+/(?:(?i)a)b/
+    Ab
+
+/((?i)a)b/
+    Ab
+
+/(?:(?i)a)b/
+    *** Failers
+    cb
+    aB
+
+/((?i)a)b/
+
+/(?i:a)b/
+    ab
+
+/((?i:a))b/
+    ab
+
+/(?i:a)b/
+    Ab
+
+/((?i:a))b/
+    Ab
+
+/(?i:a)b/
+    *** Failers
+    aB
+    aB
+
+/((?i:a))b/
+
+/(?:(?-i)a)b/i
+    ab
+
+/((?-i)a)b/i
+    ab
+
+/(?:(?-i)a)b/i
+    aB
+
+/((?-i)a)b/i
+    aB
+
+/(?:(?-i)a)b/i
+    *** Failers
+    aB
+    Ab
+
+/((?-i)a)b/i
+
+/(?:(?-i)a)b/i
+    aB
+
+/((?-i)a)b/i
+    aB
+
+/(?:(?-i)a)b/i
+    *** Failers
+    Ab
+    AB
+
+/((?-i)a)b/i
+
+/(?-i:a)b/i
+    ab
+
+/((?-i:a))b/i
+    ab
+
+/(?-i:a)b/i
+    aB
+
+/((?-i:a))b/i
+    aB
+
+/(?-i:a)b/i
+    *** Failers
+    AB
+    Ab
+
+/((?-i:a))b/i
+
+/(?-i:a)b/i
+    aB
+
+/((?-i:a))b/i
+    aB
+
+/(?-i:a)b/i
+    *** Failers
+    Ab
+    AB
+
+/((?-i:a))b/i
+
+/((?-i:a.))b/i
+    *** Failers
+    AB
+    a\nB
+
+/((?s-i:a.))b/i
+    a\nB
+
+/(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))/
+    cabbbb
+
+/(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))/
+    caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+
+/(ab)\d\1/i
+    Ab4ab
+    ab4Ab
+
+/foo\w*\d{4}baz/
+    foobar1234baz
+
+/x(~~)*(?:(?:F)?)?/
+    x~~
+
+/^a(?#xxx){3}c/
+    aaac
+
+/^a (?#xxx) (?#yyy) {3}c/x
+    aaac
+
+/(?<![cd])b/
+    *** Failers
+    B\nB
+    dbcb
+
+/(?<![cd])[ab]/
+    dbaacb
+
+/(?<!(c|d))b/
+
+/(?<!(c|d))[ab]/
+    dbaacb
+
+/(?<!cd)[ab]/
+    cdaccb
+
+/^(?:a?b?)*$/
+    *** Failers
+    dbcb
+    a--
+
+/((?s)^a(.))((?m)^b$)/
+    a\nb\nc\n
+
+/((?m)^b$)/
+    a\nb\nc\n
+
+/(?m)^b/
+    a\nb\n
+
+/(?m)^(b)/
+    a\nb\n
+
+/((?m)^b)/
+    a\nb\n
+
+/\n((?m)^b)/
+    a\nb\n
+
+/((?s).)c(?!.)/
+    a\nb\nc\n
+    a\nb\nc\n
+
+/((?s)b.)c(?!.)/
+    a\nb\nc\n
+    a\nb\nc\n
+
+/^b/
+
+/()^b/
+    *** Failers
+    a\nb\nc\n
+    a\nb\nc\n
+
+/((?m)^b)/
+    a\nb\nc\n
+
+/(?(1)a|b)/
+
+/(?(1)b|a)/
+    a
+
+/(x)?(?(1)a|b)/
+    *** Failers
+    a
+    a
+
+/(x)?(?(1)b|a)/
+    a
+
+/()?(?(1)b|a)/
+    a
+
+/()(?(1)b|a)/
+
+/()?(?(1)a|b)/
+    a
+
+/^(\()?blah(?(1)(\)))$/
+    (blah)
+    blah
+    *** Failers
+    a
+    blah)
+    (blah
+
+/^(\(+)?blah(?(1)(\)))$/
+    (blah)
+    blah
+    *** Failers
+    blah)
+    (blah
+
+/(?(?!a)a|b)/
+
+/(?(?!a)b|a)/
+    a
+
+/(?(?=a)b|a)/
+    *** Failers
+    a
+    a
+
+/(?(?=a)a|b)/
+    a
+
+/(?=(a+?))(\1ab)/
+    aaab
+
+/^(?=(a+?))\1ab/
+
+/(\w+:)+/
+    one:
+
+/$(?<=^(a))/
+    a
+
+/(?=(a+?))(\1ab)/
+    aaab
+
+/^(?=(a+?))\1ab/
+    *** Failers
+    aaab
+    aaab
+
+/([\w:]+::)?(\w+)$/
+    abcd
+    xy:z:::abcd
+
+/^[^bcd]*(c+)/
+    aexycd
+
+/(a*)b+/
+    caab
+
+/([\w:]+::)?(\w+)$/
+    abcd
+    xy:z:::abcd
+    *** Failers
+    abcd:
+    abcd:
+
+/^[^bcd]*(c+)/
+    aexycd
+
+/(>a+)ab/
+
+/(?>a+)b/
+    aaab
+
+/([[:]+)/
+    a:[b]:
+
+/([[=]+)/
+    a=[b]=
+
+/([[.]+)/
+    a.[b].
+
+/((?>a+)b)/
+    aaab
+
+/(?>(a+))b/
+    aaab
+
+/((?>[^()]+)|\([^()]*\))+/
+    ((abc(ade)ufh()()x
+
+/a\Z/
+    *** Failers
+    aaab
+    a\nb\n
+
+/b\Z/
+    a\nb\n
+
+/b\z/
+
+/b\Z/
+    a\nb
+
+/b\z/
+    a\nb
+    *** Failers
+    
+/^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$/
+    a
+    abc
+    a-b
+    0-9 
+    a.b
+    5.6.7  
+    the.quick.brown.fox
+    a100.b200.300c  
+    12-ab.1245 
+    ***Failers
+    \
+    .a
+    -a
+    a-
+    a.  
+    a_b 
+    a.-
+    a..  
+    ab..bc 
+    the.quick.brown.fox-
+    the.quick.brown.fox.
+    the.quick.brown.fox_
+    the.quick.brown.fox+       
+
+/(?>.*)(?<=(abcd|wxyz))/
+    alphabetabcd
+    endingwxyz
+    *** Failers
+    a rather long string that doesn't end with one of them
+
+/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/
+    word cat dog elephant mussel cow horse canary baboon snake shark otherword
+    word cat dog elephant mussel cow horse canary baboon snake shark
+  
+/word (?>[a-zA-Z0-9]+ ){0,30}otherword/
+    word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope
+
+/(?<=\d{3}(?!999))foo/
+    999foo
+    123999foo 
+    *** Failers
+    123abcfoo
+    
+/(?<=(?!...999)\d{3})foo/
+    999foo
+    123999foo 
+    *** Failers
+    123abcfoo
+
+/(?<=\d{3}(?!999)...)foo/
+    123abcfoo
+    123456foo 
+    *** Failers
+    123999foo  
+    
+/(?<=\d{3}...)(?<!999)foo/
+    123abcfoo   
+    123456foo 
+    *** Failers
+    123999foo  
+
+/<a[\s]+href[\s]*=[\s]*          # find <a href=
+ ([\"\'])?                       # find single or double quote
+ (?(1) (.*?)\1 | ([^\s]+))       # if quote found, match up to next matching
+                                 # quote, otherwise match up to next space
+/isx
+    <a href=abcd xyz
+    <a href=\"abcd xyz pqr\" cats
+    <a href=\'abcd xyz pqr\' cats
+
+/<a\s+href\s*=\s*                # find <a href=
+ (["'])?                         # find single or double quote
+ (?(1) (.*?)\1 | (\S+))          # if quote found, match up to next matching
+                                 # quote, otherwise match up to next space
+/isx
+    <a href=abcd xyz
+    <a href=\"abcd xyz pqr\" cats
+    <a href       =       \'abcd xyz pqr\' cats
+
+/<a\s+href(?>\s*)=(?>\s*)        # find <a href=
+ (["'])?                         # find single or double quote
+ (?(1) (.*?)\1 | (\S+))          # if quote found, match up to next matching
+                                 # quote, otherwise match up to next space
+/isx
+    <a href=abcd xyz
+    <a href=\"abcd xyz pqr\" cats
+    <a href       =       \'abcd xyz pqr\' cats
+
+/ End of test input /       
diff --git a/ext/pcre/pcrelib/testdata/testinput4 b/ext/pcre/pcrelib/testdata/testinput4
new file mode 100644 (file)
index 0000000..c23b52a
--- /dev/null
@@ -0,0 +1,64 @@
+/^[\w]+/
+    *** Failers
+    École
+
+/^[\w]+/Lfr
+    École
+
+/^[\w]+/
+    *** Failers
+    École
+
+/^[\W]+/
+    École
+
+/^[\W]+/Lfr
+    *** Failers
+    École
+
+/[\b]/
+    \b
+    *** Failers
+    a
+
+/[\b]/Lfr
+    \b
+    *** Failers
+    a
+
+/^\w+/
+    *** Failers
+    École
+
+/^\w+/Lfr
+    École
+
+/(.+)\b(.+)/
+    École
+
+/(.+)\b(.+)/Lfr
+    *** Failers
+    École
+
+/École/i
+    École
+    *** Failers
+    école
+
+/École/iLfr
+    École
+    école
+
+/\w/IS
+
+/\w/ISLfr
+
+/^[\xc8-\xc9]/iLfr
+    École
+    école
+
+/^[\xc8-\xc9]/Lfr
+    École
+    *** Failers 
+    école
+
diff --git a/ext/pcre/pcrelib/testdata/testoutput1 b/ext/pcre/pcrelib/testdata/testoutput1
new file mode 100644 (file)
index 0000000..19032e1
--- /dev/null
@@ -0,0 +1,2925 @@
+PCRE version 3.1 09-Feb-2000
+
+/the quick brown fox/
+    the quick brown fox
+ 0: the quick brown fox
+    The quick brown FOX
+No match
+    What do you know about the quick brown fox?
+ 0: the quick brown fox
+    What do you know about THE QUICK BROWN FOX?
+No match
+
+/The quick brown fox/i
+    the quick brown fox
+ 0: the quick brown fox
+    The quick brown FOX
+ 0: The quick brown FOX
+    What do you know about the quick brown fox?
+ 0: the quick brown fox
+    What do you know about THE QUICK BROWN FOX?
+ 0: THE QUICK BROWN FOX
+
+/abcd\t\n\r\f\a\e\071\x3b\$\\\?caxyz/
+    abcd\t\n\r\f\a\e9;\$\\?caxyz
+ 0: abcd\x09\x0a\x0d\x0c\x07\x1b9;$\?caxyz
+
+/a*abc?xyz+pqr{3}ab{2,}xy{4,5}pq{0,6}AB{0,}zz/
+    abxyzpqrrrabbxyyyypqAzz
+ 0: abxyzpqrrrabbxyyyypqAzz
+    abxyzpqrrrabbxyyyypqAzz
+ 0: abxyzpqrrrabbxyyyypqAzz
+    aabxyzpqrrrabbxyyyypqAzz
+ 0: aabxyzpqrrrabbxyyyypqAzz
+    aaabxyzpqrrrabbxyyyypqAzz
+ 0: aaabxyzpqrrrabbxyyyypqAzz
+    aaaabxyzpqrrrabbxyyyypqAzz
+ 0: aaaabxyzpqrrrabbxyyyypqAzz
+    abcxyzpqrrrabbxyyyypqAzz
+ 0: abcxyzpqrrrabbxyyyypqAzz
+    aabcxyzpqrrrabbxyyyypqAzz
+ 0: aabcxyzpqrrrabbxyyyypqAzz
+    aaabcxyzpqrrrabbxyyyypAzz
+ 0: aaabcxyzpqrrrabbxyyyypAzz
+    aaabcxyzpqrrrabbxyyyypqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqAzz
+    aaabcxyzpqrrrabbxyyyypqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqAzz
+    aaabcxyzpqrrrabbxyyyypqqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqqAzz
+    aaabcxyzpqrrrabbxyyyypqqqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqqqAzz
+    aaabcxyzpqrrrabbxyyyypqqqqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqqqqAzz
+    aaabcxyzpqrrrabbxyyyypqqqqqqAzz
+ 0: aaabcxyzpqrrrabbxyyyypqqqqqqAzz
+    aaaabcxyzpqrrrabbxyyyypqAzz
+ 0: aaaabcxyzpqrrrabbxyyyypqAzz
+    abxyzzpqrrrabbxyyyypqAzz
+ 0: abxyzzpqrrrabbxyyyypqAzz
+    aabxyzzzpqrrrabbxyyyypqAzz
+ 0: aabxyzzzpqrrrabbxyyyypqAzz
+    aaabxyzzzzpqrrrabbxyyyypqAzz
+ 0: aaabxyzzzzpqrrrabbxyyyypqAzz
+    aaaabxyzzzzpqrrrabbxyyyypqAzz
+ 0: aaaabxyzzzzpqrrrabbxyyyypqAzz
+    abcxyzzpqrrrabbxyyyypqAzz
+ 0: abcxyzzpqrrrabbxyyyypqAzz
+    aabcxyzzzpqrrrabbxyyyypqAzz
+ 0: aabcxyzzzpqrrrabbxyyyypqAzz
+    aaabcxyzzzzpqrrrabbxyyyypqAzz
+ 0: aaabcxyzzzzpqrrrabbxyyyypqAzz
+    aaaabcxyzzzzpqrrrabbxyyyypqAzz
+ 0: aaaabcxyzzzzpqrrrabbxyyyypqAzz
+    aaaabcxyzzzzpqrrrabbbxyyyypqAzz
+ 0: aaaabcxyzzzzpqrrrabbbxyyyypqAzz
+    aaaabcxyzzzzpqrrrabbbxyyyyypqAzz
+ 0: aaaabcxyzzzzpqrrrabbbxyyyyypqAzz
+    aaabcxyzpqrrrabbxyyyypABzz
+ 0: aaabcxyzpqrrrabbxyyyypABzz
+    aaabcxyzpqrrrabbxyyyypABBzz
+ 0: aaabcxyzpqrrrabbxyyyypABBzz
+    >>>aaabxyzpqrrrabbxyyyypqAzz
+ 0: aaabxyzpqrrrabbxyyyypqAzz
+    >aaaabxyzpqrrrabbxyyyypqAzz
+ 0: aaaabxyzpqrrrabbxyyyypqAzz
+    >>>>abcxyzpqrrrabbxyyyypqAzz
+ 0: abcxyzpqrrrabbxyyyypqAzz
+    *** Failers
+No match
+    abxyzpqrrabbxyyyypqAzz
+No match
+    abxyzpqrrrrabbxyyyypqAzz
+No match
+    abxyzpqrrrabxyyyypqAzz
+No match
+    aaaabcxyzzzzpqrrrabbbxyyyyyypqAzz
+No match
+    aaaabcxyzzzzpqrrrabbbxyyypqAzz
+No match
+    aaabcxyzpqrrrabbxyyyypqqqqqqqAzz
+No match
+
+/^(abc){1,2}zz/
+    abczz
+ 0: abczz
+ 1: abc
+    abcabczz
+ 0: abcabczz
+ 1: abc
+    *** Failers
+No match
+    zz
+No match
+    abcabcabczz
+No match
+    >>abczz
+No match
+
+/^(b+?|a){1,2}?c/
+    bc
+ 0: bc
+ 1: b
+    bbc
+ 0: bbc
+ 1: b
+    bbbc
+ 0: bbbc
+ 1: bb
+    bac
+ 0: bac
+ 1: a
+    bbac
+ 0: bbac
+ 1: a
+    aac
+ 0: aac
+ 1: a
+    abbbbbbbbbbbc
+ 0: abbbbbbbbbbbc
+ 1: bbbbbbbbbbb
+    bbbbbbbbbbbac
+ 0: bbbbbbbbbbbac
+ 1: a
+    *** Failers
+No match
+    aaac
+No match
+    abbbbbbbbbbbac
+No match
+
+/^(b+|a){1,2}c/
+    bc
+ 0: bc
+ 1: b
+    bbc
+ 0: bbc
+ 1: bb
+    bbbc
+ 0: bbbc
+ 1: bbb
+    bac
+ 0: bac
+ 1: a
+    bbac
+ 0: bbac
+ 1: a
+    aac
+ 0: aac
+ 1: a
+    abbbbbbbbbbbc
+ 0: abbbbbbbbbbbc
+ 1: bbbbbbbbbbb
+    bbbbbbbbbbbac
+ 0: bbbbbbbbbbbac
+ 1: a
+    *** Failers
+No match
+    aaac
+No match
+    abbbbbbbbbbbac
+No match
+
+/^(b+|a){1,2}?bc/
+    bbc
+ 0: bbc
+ 1: b
+
+/^(b*|ba){1,2}?bc/
+    babc
+ 0: babc
+ 1: ba
+    bbabc
+ 0: bbabc
+ 1: ba
+    bababc
+ 0: bababc
+ 1: ba
+    *** Failers
+No match
+    bababbc
+No match
+    babababc
+No match
+
+/^(ba|b*){1,2}?bc/
+    babc
+ 0: babc
+ 1: ba
+    bbabc
+ 0: bbabc
+ 1: ba
+    bababc
+ 0: bababc
+ 1: ba
+    *** Failers
+No match
+    bababbc
+No match
+    babababc
+No match
+
+/^\ca\cA\c[\c{\c:/
+    \x01\x01\e;z
+ 0: \x01\x01\x1b;z
+
+/^[ab\]cde]/
+    athing
+ 0: a
+    bthing
+ 0: b
+    ]thing
+ 0: ]
+    cthing
+ 0: c
+    dthing
+ 0: d
+    ething
+ 0: e
+    *** Failers
+No match
+    fthing
+No match
+    [thing
+No match
+    \\thing
+No match
+
+/^[]cde]/
+    ]thing
+ 0: ]
+    cthing
+ 0: c
+    dthing
+ 0: d
+    ething
+ 0: e
+    *** Failers
+No match
+    athing
+No match
+    fthing
+No match
+
+/^[^ab\]cde]/
+    fthing
+ 0: f
+    [thing
+ 0: [
+    \\thing
+ 0: \
+    *** Failers
+ 0: *
+    athing
+No match
+    bthing
+No match
+    ]thing
+No match
+    cthing
+No match
+    dthing
+No match
+    ething
+No match
+
+/^[^]cde]/
+    athing
+ 0: a
+    fthing
+ 0: f
+    *** Failers
+ 0: *
+    ]thing
+No match
+    cthing
+No match
+    dthing
+No match
+    ething
+No match
+
+/^\\81/
+    \81
+ 0: \x81
+
+/^ÿ/
+    ÿ
+ 0: \xff
+
+/^[0-9]+$/
+    0
+ 0: 0
+    1
+ 0: 1
+    2
+ 0: 2
+    3
+ 0: 3
+    4
+ 0: 4
+    5
+ 0: 5
+    6
+ 0: 6
+    7
+ 0: 7
+    8
+ 0: 8
+    9
+ 0: 9
+    10
+ 0: 10
+    100
+ 0: 100
+    *** Failers
+No match
+    abc
+No match
+
+/^.*nter/
+    enter
+ 0: enter
+    inter
+ 0: inter
+    uponter
+ 0: uponter
+
+/^xxx[0-9]+$/
+    xxx0
+ 0: xxx0
+    xxx1234
+ 0: xxx1234
+    *** Failers
+No match
+    xxx
+No match
+
+/^.+[0-9][0-9][0-9]$/
+    x123
+ 0: x123
+    xx123
+ 0: xx123
+    123456
+ 0: 123456
+    *** Failers
+No match
+    123
+No match
+    x1234
+ 0: x1234
+
+/^.+?[0-9][0-9][0-9]$/
+    x123
+ 0: x123
+    xx123
+ 0: xx123
+    123456
+ 0: 123456
+    *** Failers
+No match
+    123
+No match
+    x1234
+ 0: x1234
+
+/^([^!]+)!(.+)=apquxz\.ixr\.zzz\.ac\.uk$/
+    abc!pqr=apquxz.ixr.zzz.ac.uk
+ 0: abc!pqr=apquxz.ixr.zzz.ac.uk
+ 1: abc
+ 2: pqr
+    *** Failers
+No match
+    !pqr=apquxz.ixr.zzz.ac.uk
+No match
+    abc!=apquxz.ixr.zzz.ac.uk
+No match
+    abc!pqr=apquxz:ixr.zzz.ac.uk
+No match
+    abc!pqr=apquxz.ixr.zzz.ac.ukk
+No match
+
+/:/
+    Well, we need a colon: somewhere
+ 0: :
+    *** Fail if we don't
+No match
+
+/([\da-f:]+)$/i
+    0abc
+ 0: 0abc
+ 1: 0abc
+    abc
+ 0: abc
+ 1: abc
+    fed
+ 0: fed
+ 1: fed
+    E
+ 0: E
+ 1: E
+    ::
+ 0: ::
+ 1: ::
+    5f03:12C0::932e
+ 0: 5f03:12C0::932e
+ 1: 5f03:12C0::932e
+    fed def
+ 0: def
+ 1: def
+    Any old stuff
+ 0: ff
+ 1: ff
+    *** Failers
+No match
+    0zzz
+No match
+    gzzz
+No match
+    fed\x20
+No match
+    Any old rubbish
+No match
+
+/^.*\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/
+    .1.2.3
+ 0: .1.2.3
+ 1: 1
+ 2: 2
+ 3: 3
+    A.12.123.0
+ 0: A.12.123.0
+ 1: 12
+ 2: 123
+ 3: 0
+    *** Failers
+No match
+    .1.2.3333
+No match
+    1.2.3
+No match
+    1234.2.3
+No match
+
+/^(\d+)\s+IN\s+SOA\s+(\S+)\s+(\S+)\s*\(\s*$/
+    1 IN SOA non-sp1 non-sp2(
+ 0: 1 IN SOA non-sp1 non-sp2(
+ 1: 1
+ 2: non-sp1
+ 3: non-sp2
+    1    IN    SOA    non-sp1    non-sp2   (
+ 0: 1    IN    SOA    non-sp1    non-sp2   (
+ 1: 1
+ 2: non-sp1
+ 3: non-sp2
+    *** Failers
+No match
+    1IN SOA non-sp1 non-sp2(
+No match
+
+/^[a-zA-Z\d][a-zA-Z\d\-]*(\.[a-zA-Z\d][a-zA-z\d\-]*)*\.$/
+    a.
+ 0: a.
+    Z.
+ 0: Z.
+    2.
+ 0: 2.
+    ab-c.pq-r.
+ 0: ab-c.pq-r.
+ 1: .pq-r
+    sxk.zzz.ac.uk.
+ 0: sxk.zzz.ac.uk.
+ 1: .uk
+    x-.y-.
+ 0: x-.y-.
+ 1: .y-
+    *** Failers
+No match
+    -abc.peq.
+No match
+
+/^\*\.[a-z]([a-z\-\d]*[a-z\d]+)?(\.[a-z]([a-z\-\d]*[a-z\d]+)?)*$/
+    *.a
+ 0: *.a
+    *.b0-a
+ 0: *.b0-a
+ 1: 0-a
+    *.c3-b.c
+ 0: *.c3-b.c
+ 1: 3-b
+ 2: .c
+    *.c-a.b-c
+ 0: *.c-a.b-c
+ 1: -a
+ 2: .b-c
+ 3: -c
+    *** Failers
+No match
+    *.0
+No match
+    *.a-
+No match
+    *.a-b.c-
+No match
+    *.c-a.0-c
+No match
+
+/^(?=ab(de))(abd)(e)/
+    abde
+ 0: abde
+ 1: de
+ 2: abd
+ 3: e
+
+/^(?!(ab)de|x)(abd)(f)/
+    abdf
+ 0: abdf
+ 1: <unset>
+ 2: abd
+ 3: f
+
+/^(?=(ab(cd)))(ab)/
+    abcd
+ 0: ab
+ 1: abcd
+ 2: cd
+ 3: ab
+
+/^[\da-f](\.[\da-f])*$/i
+    a.b.c.d
+ 0: a.b.c.d
+ 1: .d
+    A.B.C.D
+ 0: A.B.C.D
+ 1: .D
+    a.b.c.1.2.3.C
+ 0: a.b.c.1.2.3.C
+ 1: .C
+
+/^\".*\"\s*(;.*)?$/
+    \"1234\"
+ 0: "1234"
+    \"abcd\" ;
+ 0: "abcd" ;
+ 1: ;
+    \"\" ; rhubarb
+ 0: "" ; rhubarb
+ 1: ; rhubarb
+    *** Failers
+No match
+    \"1234\" : things
+No match
+
+/^$/
+    \
+ 0: 
+    *** Failers
+No match
+
+/   ^    a   (?# begins with a)  b\sc (?# then b c) $ (?# then end)/x
+    ab c
+ 0: ab c
+    *** Failers
+No match
+    abc
+No match
+    ab cde
+No match
+
+/(?x)   ^    a   (?# begins with a)  b\sc (?# then b c) $ (?# then end)/
+    ab c
+ 0: ab c
+    *** Failers
+No match
+    abc
+No match
+    ab cde
+No match
+
+/^   a\ b[c ]d       $/x
+    a bcd
+ 0: a bcd
+    a b d
+ 0: a b d
+    *** Failers
+No match
+    abcd
+No match
+    ab d
+No match
+
+/^(a(b(c)))(d(e(f)))(h(i(j)))(k(l(m)))$/
+    abcdefhijklm
+ 0: abcdefhijklm
+ 1: abc
+ 2: bc
+ 3: c
+ 4: def
+ 5: ef
+ 6: f
+ 7: hij
+ 8: ij
+ 9: j
+10: klm
+11: lm
+12: m
+
+/^(?:a(b(c)))(?:d(e(f)))(?:h(i(j)))(?:k(l(m)))$/
+    abcdefhijklm
+ 0: abcdefhijklm
+ 1: bc
+ 2: c
+ 3: ef
+ 4: f
+ 5: ij
+ 6: j
+ 7: lm
+ 8: m
+
+/^[\w][\W][\s][\S][\d][\D][\b][\n][\c]][\022]/
+    a+ Z0+\x08\n\x1d\x12
+ 0: a+ Z0+\x08\x0a\x1d\x12
+
+/^[.^$|()*+?{,}]+/
+    .^\$(*+)|{?,?}
+ 0: .^$(*+)|{?,?}
+
+/^a*\w/
+    z
+ 0: z
+    az
+ 0: az
+    aaaz
+ 0: aaaz
+    a
+ 0: a
+    aa
+ 0: aa
+    aaaa
+ 0: aaaa
+    a+
+ 0: a
+    aa+
+ 0: aa
+
+/^a*?\w/
+    z
+ 0: z
+    az
+ 0: a
+    aaaz
+ 0: a
+    a
+ 0: a
+    aa
+ 0: a
+    aaaa
+ 0: a
+    a+
+ 0: a
+    aa+
+ 0: a
+
+/^a+\w/
+    az
+ 0: az
+    aaaz
+ 0: aaaz
+    aa
+ 0: aa
+    aaaa
+ 0: aaaa
+    aa+
+ 0: aa
+
+/^a+?\w/
+    az
+ 0: az
+    aaaz
+ 0: aa
+    aa
+ 0: aa
+    aaaa
+ 0: aa
+    aa+
+ 0: aa
+
+/^\d{8}\w{2,}/
+    1234567890
+ 0: 1234567890
+    12345678ab
+ 0: 12345678ab
+    12345678__
+ 0: 12345678__
+    *** Failers
+No match
+    1234567
+No match
+
+/^[aeiou\d]{4,5}$/
+    uoie
+ 0: uoie
+    1234
+ 0: 1234
+    12345
+ 0: 12345
+    aaaaa
+ 0: aaaaa
+    *** Failers
+No match
+    123456
+No match
+
+/^[aeiou\d]{4,5}?/
+    uoie
+ 0: uoie
+    1234
+ 0: 1234
+    12345
+ 0: 1234
+    aaaaa
+ 0: aaaa
+    123456
+ 0: 1234
+
+/\A(abc|def)=(\1){2,3}\Z/
+    abc=abcabc
+ 0: abc=abcabc
+ 1: abc
+ 2: abc
+    def=defdefdef
+ 0: def=defdefdef
+ 1: def
+ 2: def
+    *** Failers
+No match
+    abc=defdef
+No match
+
+/^(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\11*(\3\4)\1(?#)2$/
+    abcdefghijkcda2
+ 0: abcdefghijkcda2
+ 1: a
+ 2: b
+ 3: c
+ 4: d
+ 5: e
+ 6: f
+ 7: g
+ 8: h
+ 9: i
+10: j
+11: k
+12: cd
+    abcdefghijkkkkcda2
+ 0: abcdefghijkkkkcda2
+ 1: a
+ 2: b
+ 3: c
+ 4: d
+ 5: e
+ 6: f
+ 7: g
+ 8: h
+ 9: i
+10: j
+11: k
+12: cd
+
+/(cat(a(ract|tonic)|erpillar)) \1()2(3)/
+    cataract cataract23
+ 0: cataract cataract23
+ 1: cataract
+ 2: aract
+ 3: ract
+ 4: 
+ 5: 3
+    catatonic catatonic23
+ 0: catatonic catatonic23
+ 1: catatonic
+ 2: atonic
+ 3: tonic
+ 4: 
+ 5: 3
+    caterpillar caterpillar23
+ 0: caterpillar caterpillar23
+ 1: caterpillar
+ 2: erpillar
+ 3: <unset>
+ 4: 
+ 5: 3
+
+
+/^From +([^ ]+) +[a-zA-Z][a-zA-Z][a-zA-Z] +[a-zA-Z][a-zA-Z][a-zA-Z] +[0-9]?[0-9] +[0-9][0-9]:[0-9][0-9]/
+    From abcd  Mon Sep 01 12:33:02 1997
+ 0: From abcd  Mon Sep 01 12:33
+ 1: abcd
+
+/^From\s+\S+\s+([a-zA-Z]{3}\s+){2}\d{1,2}\s+\d\d:\d\d/
+    From abcd  Mon Sep 01 12:33:02 1997
+ 0: From abcd  Mon Sep 01 12:33
+ 1: Sep 
+    From abcd  Mon Sep  1 12:33:02 1997
+ 0: From abcd  Mon Sep  1 12:33
+ 1: Sep  
+    *** Failers
+No match
+    From abcd  Sep 01 12:33:02 1997
+No match
+
+/^12.34/s
+    12\n34
+ 0: 12\x0a34
+    12\r34
+ 0: 12\x0d34
+
+/\w+(?=\t)/
+    the quick brown\t fox
+ 0: brown
+
+/foo(?!bar)(.*)/
+    foobar is foolish see?
+ 0: foolish see?
+ 1: lish see?
+
+/(?:(?!foo)...|^.{0,2})bar(.*)/
+    foobar crowbar etc
+ 0: rowbar etc
+ 1:  etc
+    barrel
+ 0: barrel
+ 1: rel
+    2barrel
+ 0: 2barrel
+ 1: rel
+    A barrel
+ 0: A barrel
+ 1: rel
+
+/^(\D*)(?=\d)(?!123)/
+    abc456
+ 0: abc
+ 1: abc
+    *** Failers
+No match
+    abc123
+No match
+
+/^1234(?# test newlines
+  inside)/
+    1234
+ 0: 1234
+
+/^1234 #comment in extended re
+  /x
+    1234
+ 0: 1234
+
+/#rhubarb
+  abcd/x
+    abcd
+ 0: abcd
+
+/^abcd#rhubarb/x
+    abcd
+ 0: abcd
+
+/^(a)\1{2,3}(.)/
+    aaab
+ 0: aaab
+ 1: a
+ 2: b
+    aaaab
+ 0: aaaab
+ 1: a
+ 2: b
+    aaaaab
+ 0: aaaaa
+ 1: a
+ 2: a
+    aaaaaab
+ 0: aaaaa
+ 1: a
+ 2: a
+
+/(?!^)abc/
+    the abc
+ 0: abc
+    *** Failers
+No match
+    abc
+No match
+
+/(?=^)abc/
+    abc
+ 0: abc
+    *** Failers
+No match
+    the abc
+No match
+
+/^[ab]{1,3}(ab*|b)/
+    aabbbbb
+ 0: aabb
+ 1: b
+
+/^[ab]{1,3}?(ab*|b)/
+    aabbbbb
+ 0: aabbbbb
+ 1: abbbbb
+
+/^[ab]{1,3}?(ab*?|b)/
+    aabbbbb
+ 0: aa
+ 1: a
+
+/^[ab]{1,3}(ab*?|b)/
+    aabbbbb
+ 0: aabb
+ 1: b
+
+/  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*                          # optional leading comment
+(?:    (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?:                      # opening quote...
+[^\\\x80-\xff\n\015"]                #   Anything except backslash and quote
+|                     #    or
+\\ [^\x80-\xff]           #   Escaped something (something != CR)
+)* "  # closing quote
+)                    # initial word
+(?:  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  \.  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*   (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?:                      # opening quote...
+[^\\\x80-\xff\n\015"]                #   Anything except backslash and quote
+|                     #    or
+\\ [^\x80-\xff]           #   Escaped something (something != CR)
+)* "  # closing quote
+)  )* # further okay, if led by a period
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  @  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*    (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                           # initial subdomain
+(?:                                  #
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  \.                        # if led by a period...
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*   (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                     #   ...further okay
+)*
+# address
+|                     #  or
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?:                      # opening quote...
+[^\\\x80-\xff\n\015"]                #   Anything except backslash and quote
+|                     #    or
+\\ [^\x80-\xff]           #   Escaped something (something != CR)
+)* "  # closing quote
+)             # one word, optionally followed by....
+(?:
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037]  |  # atom and space parts, or...
+\(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)       |  # comments, or...
+
+" (?:                      # opening quote...
+[^\\\x80-\xff\n\015"]                #   Anything except backslash and quote
+|                     #    or
+\\ [^\x80-\xff]           #   Escaped something (something != CR)
+)* "  # closing quote
+# quoted strings
+)*
+<  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*                     # leading <
+(?:  @  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*    (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                           # initial subdomain
+(?:                                  #
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  \.                        # if led by a period...
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*   (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                     #   ...further okay
+)*
+
+(?:  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  ,  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  @  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*    (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                           # initial subdomain
+(?:                                  #
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  \.                        # if led by a period...
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*   (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                     #   ...further okay
+)*
+)* # further okay, if led by comma
+:                                # closing colon
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  )? #       optional route
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?:                      # opening quote...
+[^\\\x80-\xff\n\015"]                #   Anything except backslash and quote
+|                     #    or
+\\ [^\x80-\xff]           #   Escaped something (something != CR)
+)* "  # closing quote
+)                    # initial word
+(?:  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  \.  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*   (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+" (?:                      # opening quote...
+[^\\\x80-\xff\n\015"]                #   Anything except backslash and quote
+|                     #    or
+\\ [^\x80-\xff]           #   Escaped something (something != CR)
+)* "  # closing quote
+)  )* # further okay, if led by a period
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  @  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*    (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                           # initial subdomain
+(?:                                  #
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  \.                        # if led by a period...
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*   (?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|   \[                         # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*    #    stuff
+\]                        #           ]
+)                     #   ...further okay
+)*
+#       address spec
+(?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*  > #                  trailing >
+# name and address
+)  (?: [\040\t] |  \(
+(?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  |  \( (?:  [^\\\x80-\xff\n\015()]  |  \\ [^\x80-\xff]  )* \)  )*
+\)  )*                       # optional trailing comment
+/x
+    Alan Other <user\@dom.ain>
+ 0: Alan Other <user@dom.ain>
+    <user\@dom.ain>
+ 0: user@dom.ain
+    user\@dom.ain
+ 0: user@dom.ain
+    \"A. Other\" <user.1234\@dom.ain> (a comment)
+ 0: "A. Other" <user.1234@dom.ain> (a comment)
+    A. Other <user.1234\@dom.ain> (a comment)
+ 0:  Other <user.1234@dom.ain> (a comment)
+    \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay
+ 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay
+    A missing angle <user\@some.where
+ 0: user@some.where
+    *** Failers
+No match
+    The quick brown fox
+No match
+
+/[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional leading comment
+(?:
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+|                       #  or
+"                                     # "
+[^\\\x80-\xff\n\015"] *                            #   normal
+(?:  \\ [^\x80-\xff]  [^\\\x80-\xff\n\015"] * )*        #   ( special normal* )*
+"                                     #        "
+# Quoted string
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+\.
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+|                       #  or
+"                                     # "
+[^\\\x80-\xff\n\015"] *                            #   normal
+(?:  \\ [^\x80-\xff]  [^\\\x80-\xff\n\015"] * )*        #   ( special normal* )*
+"                                     #        "
+# Quoted string
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# additional words
+)*
+@
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+)*
+# address
+|                             #  or
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+|                       #  or
+"                                     # "
+[^\\\x80-\xff\n\015"] *                            #   normal
+(?:  \\ [^\x80-\xff]  [^\\\x80-\xff\n\015"] * )*        #   ( special normal* )*
+"                                     #        "
+# Quoted string
+)
+# leading word
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] *               # "normal" atoms and or spaces
+(?:
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+|
+"                                     # "
+[^\\\x80-\xff\n\015"] *                            #   normal
+(?:  \\ [^\x80-\xff]  [^\\\x80-\xff\n\015"] * )*        #   ( special normal* )*
+"                                     #        "
+) # "special" comment or quoted string
+[^()<>@,;:".\\\[\]\x80-\xff\000-\010\012-\037] *            #  more "normal"
+)*
+<
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# <
+(?:
+@
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+)*
+(?: ,
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+@
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+)*
+)*  # additional domains
+:
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+)?     #       optional route
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+|                       #  or
+"                                     # "
+[^\\\x80-\xff\n\015"] *                            #   normal
+(?:  \\ [^\x80-\xff]  [^\\\x80-\xff\n\015"] * )*        #   ( special normal* )*
+"                                     #        "
+# Quoted string
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+\.
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+# Atom
+|                       #  or
+"                                     # "
+[^\\\x80-\xff\n\015"] *                            #   normal
+(?:  \\ [^\x80-\xff]  [^\\\x80-\xff\n\015"] * )*        #   ( special normal* )*
+"                                     #        "
+# Quoted string
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# additional words
+)*
+@
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+(?:
+\.
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+(?:
+[^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]+    # some number of atom characters...
+(?![^(\040)<>@,;:".\\\[\]\000-\037\x80-\xff]) # ..not followed by something that could be part of an atom
+|
+\[                            # [
+(?: [^\\\x80-\xff\n\015\[\]] |  \\ [^\x80-\xff]  )*     #    stuff
+\]                           #           ]
+)
+[\040\t]*                    # Nab whitespace.
+(?:
+\(                              #  (
+[^\\\x80-\xff\n\015()] *                             #     normal*
+(?:                                 #       (
+(?:  \\ [^\x80-\xff]  |
+\(                            #  (
+[^\\\x80-\xff\n\015()] *                            #     normal*
+(?:  \\ [^\x80-\xff]   [^\\\x80-\xff\n\015()] * )*        #     (special normal*)*
+\)                           #                       )
+)    #         special
+[^\\\x80-\xff\n\015()] *                         #         normal*
+)*                                  #            )*
+\)                             #                )
+[\040\t]* )*    # If comment found, allow more spaces.
+# optional trailing comments
+)*
+#       address spec
+>                    #                 >
+# name and address
+)
+/x
+    Alan Other <user\@dom.ain>
+ 0: Alan Other <user@dom.ain>
+    <user\@dom.ain>
+ 0: user@dom.ain
+    user\@dom.ain
+ 0: user@dom.ain
+    \"A. Other\" <user.1234\@dom.ain> (a comment)
+ 0: "A. Other" <user.1234@dom.ain>
+    A. Other <user.1234\@dom.ain> (a comment)
+ 0:  Other <user.1234@dom.ain>
+    \"/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/\"\@x400-re.lay
+ 0: "/s=user/ou=host/o=place/prmd=uu.yy/admd= /c=gb/"@x400-re.lay
+    A missing angle <user\@some.where
+ 0: user@some.where
+    *** Failers
+No match
+    The quick brown fox
+No match
+
+/abc\0def\00pqr\000xyz\0000AB/
+    abc\0def\00pqr\000xyz\0000AB
+ 0: abc\x00def\x00pqr\x00xyz\x000AB
+    abc456 abc\0def\00pqr\000xyz\0000ABCDE
+ 0: abc\x00def\x00pqr\x00xyz\x000AB
+
+/abc\x0def\x00pqr\x000xyz\x0000AB/
+    abc\x0def\x00pqr\x000xyz\x0000AB
+ 0: abc\x0def\x00pqr\x000xyz\x0000AB
+    abc456 abc\x0def\x00pqr\x000xyz\x0000ABCDE
+ 0: abc\x0def\x00pqr\x000xyz\x0000AB
+
+/^[\000-\037]/
+    \0A
+ 0: \x00
+    \01B
+ 0: \x01
+    \037C
+ 0: \x1f
+
+/\0*/
+    \0\0\0\0
+ 0: \x00\x00\x00\x00
+
+/A\x0{2,3}Z/
+    The A\x0\x0Z
+ 0: A\x00\x00Z
+    An A\0\x0\0Z
+ 0: A\x00\x00\x00Z
+    *** Failers
+No match
+    A\0Z
+No match
+    A\0\x0\0\x0Z
+No match
+
+/^(cow|)\1(bell)/
+    cowcowbell
+ 0: cowcowbell
+ 1: cow
+ 2: bell
+    bell
+ 0: bell
+ 1: 
+ 2: bell
+    *** Failers
+No match
+    cowbell
+No match
+
+/^\s/
+    \040abc
+ 0:  
+    \x0cabc
+ 0: \x0c
+    \nabc
+ 0: \x0a
+    \rabc
+ 0: \x0d
+    \tabc
+ 0: \x09
+    *** Failers
+No match
+    abc
+No match
+
+/^a    b
+  
+  \f  c/x
+    abc
+ 0: abc
+
+/^(a|)\1*b/
+    ab
+ 0: ab
+ 1: a
+    aaaab
+ 0: aaaab
+ 1: a
+    b
+ 0: b
+ 1: 
+    *** Failers
+No match
+    acb
+No match
+
+/^(a|)\1+b/
+    aab
+ 0: aab
+ 1: a
+    aaaab
+ 0: aaaab
+ 1: a
+    b
+ 0: b
+ 1: 
+    *** Failers
+No match
+    ab
+No match
+
+/^(a|)\1?b/
+    ab
+ 0: ab
+ 1: a
+    aab
+ 0: aab
+ 1: a
+    b
+ 0: b
+ 1: 
+    *** Failers
+No match
+    acb
+No match
+
+/^(a|)\1{2}b/
+    aaab
+ 0: aaab
+ 1: a
+    b
+ 0: b
+ 1: 
+    *** Failers
+No match
+    ab
+No match
+    aab
+No match
+    aaaab
+No match
+
+/^(a|)\1{2,3}b/
+    aaab
+ 0: aaab
+ 1: a
+    aaaab
+ 0: aaaab
+ 1: a
+    b
+ 0: b
+ 1: 
+    *** Failers
+No match
+    ab
+No match
+    aab
+No match
+    aaaaab
+No match
+
+/ab{1,3}bc/
+    abbbbc
+ 0: abbbbc
+    abbbc
+ 0: abbbc
+    abbc
+ 0: abbc
+    *** Failers
+No match
+    abc
+No match
+    abbbbbc
+No match
+
+/([^.]*)\.([^:]*):[T ]+(.*)/
+    track1.title:TBlah blah blah
+ 0: track1.title:TBlah blah blah
+ 1: track1
+ 2: title
+ 3: Blah blah blah
+
+/([^.]*)\.([^:]*):[T ]+(.*)/i
+    track1.title:TBlah blah blah
+ 0: track1.title:TBlah blah blah
+ 1: track1
+ 2: title
+ 3: Blah blah blah
+
+/([^.]*)\.([^:]*):[t ]+(.*)/i
+    track1.title:TBlah blah blah
+ 0: track1.title:TBlah blah blah
+ 1: track1
+ 2: title
+ 3: Blah blah blah
+
+/^[W-c]+$/
+    WXY_^abc
+ 0: WXY_^abc
+    ***Failers
+No match
+    wxy
+No match
+
+/^[W-c]+$/i
+    WXY_^abc
+ 0: WXY_^abc
+    wxy_^ABC
+ 0: wxy_^ABC
+
+/^[\x3f-\x5F]+$/i
+    WXY_^abc
+ 0: WXY_^abc
+    wxy_^ABC
+ 0: wxy_^ABC
+
+/^abc$/m
+    abc
+ 0: abc
+    qqq\nabc
+ 0: abc
+    abc\nzzz
+ 0: abc
+    qqq\nabc\nzzz
+ 0: abc
+
+/^abc$/
+    abc
+ 0: abc
+    *** Failers
+No match
+    qqq\nabc
+No match
+    abc\nzzz
+No match
+    qqq\nabc\nzzz
+No match
+
+/\Aabc\Z/m
+    abc
+ 0: abc
+    abc\n 
+ 0: abc
+    *** Failers
+No match
+    qqq\nabc
+No match
+    abc\nzzz
+No match
+    qqq\nabc\nzzz
+No match
+    
+/\A(.)*\Z/s
+    abc\ndef
+ 0: abc\x0adef
+ 1: f
+
+/\A(.)*\Z/m
+    *** Failers
+ 0: *** Failers
+ 1: s
+    abc\ndef
+No match
+
+/(?:b)|(?::+)/
+    b::c
+ 0: b
+    c::b
+ 0: ::
+
+/[-az]+/
+    az-
+ 0: az-
+    *** Failers
+ 0: a
+    b
+No match
+
+/[az-]+/
+    za-
+ 0: za-
+    *** Failers
+ 0: a
+    b
+No match
+
+/[a\-z]+/
+    a-z
+ 0: a-z
+    *** Failers
+ 0: a
+    b
+No match
+
+/[a-z]+/
+    abcdxyz
+ 0: abcdxyz
+
+/[\d-]+/
+    12-34
+ 0: 12-34
+    *** Failers
+No match
+    aaa
+No match
+
+/[\d-z]+/
+    12-34z
+ 0: 12-34z
+    *** Failers
+No match
+    aaa
+No match
+
+/\x5c/
+    \\
+ 0: \
+
+/\x20Z/
+    the Zoo
+ 0:  Z
+    *** Failers
+No match
+    Zulu
+No match
+
+/(abc)\1/i
+    abcabc
+ 0: abcabc
+ 1: abc
+    ABCabc
+ 0: ABCabc
+ 1: ABC
+    abcABC
+ 0: abcABC
+ 1: abc
+
+/(main(O)?)+/
+    mainmain
+ 0: mainmain
+ 1: main
+    mainOmain
+ 0: mainOmain
+ 1: main
+ 2: O
+
+/ab{3cd/
+    ab{3cd
+ 0: ab{3cd
+
+/ab{3,cd/
+    ab{3,cd
+ 0: ab{3,cd
+
+/ab{3,4a}cd/
+    ab{3,4a}cd
+ 0: ab{3,4a}cd
+
+/{4,5a}bc/
+    {4,5a}bc
+ 0: {4,5a}bc
+
+/^a.b/
+    a\rb
+ 0: a\x0db
+    *** Failers
+No match
+    a\nb
+No match
+
+/abc$/
+    abc
+ 0: abc
+    abc\n
+ 0: abc
+    *** Failers
+No match
+    abc\ndef
+No match
+
+/(abc)\123/
+    abc\x53
+ 0: abcS
+ 1: abc
+
+/(abc)\223/
+    abc\x93
+ 0: abc\x93
+ 1: abc
+
+/(abc)\323/
+    abc\xd3
+ 0: abc\xd3
+ 1: abc
+
+/(abc)\500/
+    abc\x40
+ 0: abc@
+ 1: abc
+    abc\100
+ 0: abc@
+ 1: abc
+
+/(abc)\5000/
+    abc\x400
+ 0: abc@0
+ 1: abc
+    abc\x40\x30
+ 0: abc@0
+ 1: abc
+    abc\1000
+ 0: abc@0
+ 1: abc
+    abc\100\x30
+ 0: abc@0
+ 1: abc
+    abc\100\060
+ 0: abc@0
+ 1: abc
+    abc\100\60
+ 0: abc@0
+ 1: abc
+
+/abc\81/
+    abc\081
+ 0: abc\x0081
+    abc\0\x38\x31
+ 0: abc\x0081
+
+/abc\91/
+    abc\091
+ 0: abc\x0091
+    abc\0\x39\x31
+ 0: abc\x0091
+
+/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)(l)\12\123/
+    abcdefghijkllS
+ 0: abcdefghijkllS
+ 1: a
+ 2: b
+ 3: c
+ 4: d
+ 5: e
+ 6: f
+ 7: g
+ 8: h
+ 9: i
+10: j
+11: k
+12: l
+
+/(a)(b)(c)(d)(e)(f)(g)(h)(i)(j)(k)\12\123/
+    abcdefghijk\12S
+ 0: abcdefghijk\x0aS
+ 1: a
+ 2: b
+ 3: c
+ 4: d
+ 5: e
+ 6: f
+ 7: g
+ 8: h
+ 9: i
+10: j
+11: k
+
+/ab\gdef/
+    abgdef
+ 0: abgdef
+
+/a{0}bc/
+    bc
+ 0: bc
+
+/(a|(bc)){0,0}?xyz/
+    xyz
+ 0: xyz
+
+/abc[\10]de/
+    abc\010de
+ 0: abc\x08de
+
+/abc[\1]de/
+    abc\1de
+ 0: abc\x01de
+
+/(abc)[\1]de/
+    abc\1de
+ 0: abc\x01de
+ 1: abc
+
+/a.b(?s)/
+    a\nb
+ 0: a\x0ab
+
+/^([^a])([^\b])([^c]*)([^d]{3,4})/
+    baNOTccccd
+ 0: baNOTcccc
+ 1: b
+ 2: a
+ 3: NOT
+ 4: cccc
+    baNOTcccd
+ 0: baNOTccc
+ 1: b
+ 2: a
+ 3: NOT
+ 4: ccc
+    baNOTccd
+ 0: baNOTcc
+ 1: b
+ 2: a
+ 3: NO
+ 4: Tcc
+    bacccd
+ 0: baccc
+ 1: b
+ 2: a
+ 3: 
+ 4: ccc
+    *** Failers
+ 0: *** Failers
+ 1: *
+ 2: *
+ 3: * Fail
+ 4: ers
+    anything
+No match
+    b\bc   
+No match
+    baccd
+No match
+
+/[^a]/
+    Abc
+ 0: A
+  
+/[^a]/i
+    Abc 
+ 0: b
+
+/[^a]+/
+    AAAaAbc
+ 0: AAA
+  
+/[^a]+/i
+    AAAaAbc 
+ 0: bc
+
+/[^a]+/
+    bbb\nccc
+ 0: bbb\x0accc
+   
+/[^k]$/
+    abc
+ 0: c
+    *** Failers
+ 0: s
+    abk   
+No match
+   
+/[^k]{2,3}$/
+    abc
+ 0: abc
+    kbc
+ 0: bc
+    kabc 
+ 0: abc
+    *** Failers
+ 0: ers
+    abk
+No match
+    akb
+No match
+    akk 
+No match
+
+/^\d{8,}\@.+[^k]$/
+    12345678\@a.b.c.d
+ 0: 12345678@a.b.c.d
+    123456789\@x.y.z
+ 0: 123456789@x.y.z
+    *** Failers
+No match
+    12345678\@x.y.uk
+No match
+    1234567\@a.b.c.d       
+No match
+
+/(a)\1{8,}/
+    aaaaaaaaa
+ 0: aaaaaaaaa
+ 1: a
+    aaaaaaaaaa
+ 0: aaaaaaaaaa
+ 1: a
+    *** Failers
+No match
+    aaaaaaa   
+No match
+
+/[^a]/
+    aaaabcd
+ 0: b
+    aaAabcd 
+ 0: A
+
+/[^a]/i
+    aaaabcd
+ 0: b
+    aaAabcd 
+ 0: b
+
+/[^az]/
+    aaaabcd
+ 0: b
+    aaAabcd 
+ 0: A
+
+/[^az]/i
+    aaaabcd
+ 0: b
+    aaAabcd 
+ 0: b
+
+/\000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377/
+ \000\001\002\003\004\005\006\007\010\011\012\013\014\015\016\017\020\021\022\023\024\025\026\027\030\031\032\033\034\035\036\037\040\041\042\043\044\045\046\047\050\051\052\053\054\055\056\057\060\061\062\063\064\065\066\067\070\071\072\073\074\075\076\077\100\101\102\103\104\105\106\107\110\111\112\113\114\115\116\117\120\121\122\123\124\125\126\127\130\131\132\133\134\135\136\137\140\141\142\143\144\145\146\147\150\151\152\153\154\155\156\157\160\161\162\163\164\165\166\167\170\171\172\173\174\175\176\177\200\201\202\203\204\205\206\207\210\211\212\213\214\215\216\217\220\221\222\223\224\225\226\227\230\231\232\233\234\235\236\237\240\241\242\243\244\245\246\247\250\251\252\253\254\255\256\257\260\261\262\263\264\265\266\267\270\271\272\273\274\275\276\277\300\301\302\303\304\305\306\307\310\311\312\313\314\315\316\317\320\321\322\323\324\325\326\327\330\331\332\333\334\335\336\337\340\341\342\343\344\345\346\347\350\351\352\353\354\355\356\357\360\361\362\363\364\365\366\367\370\371\372\373\374\375\376\377
+ 0: \x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f !"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~\x7f\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff
+
+/P[^*]TAIRE[^*]{1,6}?LL/
+    xxxxxxxxxxxPSTAIREISLLxxxxxxxxx
+ 0: PSTAIREISLL
+
+/P[^*]TAIRE[^*]{1,}?LL/
+    xxxxxxxxxxxPSTAIREISLLxxxxxxxxx
+ 0: PSTAIREISLL
+
+/(\.\d\d[1-9]?)\d+/
+    1.230003938
+ 0: .230003938
+ 1: .23
+    1.875000282   
+ 0: .875000282
+ 1: .875
+    1.235  
+ 0: .235
+ 1: .23
+                  
+/(\.\d\d((?=0)|\d(?=\d)))/
+    1.230003938      
+ 0: .23
+ 1: .23
+ 2: 
+    1.875000282
+ 0: .875
+ 1: .875
+ 2: 5
+    *** Failers 
+No match
+    1.235 
+No match
+    
+/a(?)b/
+    ab 
+ 0: ab
+/\b(foo)\s+(\w+)/i
+    Food is on the foo table
+ 0: foo table
+ 1: foo
+ 2: table
+    
+/foo(.*)bar/
+    The food is under the bar in the barn.
+ 0: food is under the bar in the bar
+ 1: d is under the bar in the 
+    
+/foo(.*?)bar/  
+    The food is under the bar in the barn.
+ 0: food is under the bar
+ 1: d is under the 
+
+/(.*)(\d*)/
+    I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers: 53147
+ 2: 
+    
+/(.*)(\d+)/
+    I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers: 5314
+ 2: 7
+/(.*?)(\d*)/
+    I have 2 numbers: 53147
+ 0: 
+ 1: 
+ 2: 
+
+/(.*?)(\d+)/
+    I have 2 numbers: 53147
+ 0: I have 2
+ 1: I have 
+ 2: 2
+
+/(.*)(\d+)$/
+    I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers: 5314
+ 2: 7
+
+/(.*?)(\d+)$/
+    I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers: 
+ 2: 53147
+
+/(.*)\b(\d+)$/
+    I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers: 
+ 2: 53147
+
+/(.*\D)(\d+)$/
+    I have 2 numbers: 53147
+ 0: I have 2 numbers: 53147
+ 1: I have 2 numbers: 
+ 2: 53147
+
+/^\D*(?!123)/
+    ABC123
+ 0: AB
+     
+/^(\D*)(?=\d)(?!123)/
+    ABC445
+ 0: ABC
+ 1: ABC
+    *** Failers
+No match
+    ABC123
+No match
+    
+/^[W-]46]/
+    W46]789 
+ 0: W46]
+    -46]789
+ 0: -46]
+    *** Failers
+No match
+    Wall
+No match
+    Zebra
+No match
+    42
+No match
+    [abcd] 
+No match
+    ]abcd[
+No match
+       
+/^[W-\]46]/
+    W46]789 
+ 0: W
+    Wall
+ 0: W
+    Zebra
+ 0: Z
+    Xylophone  
+ 0: X
+    42
+ 0: 4
+    [abcd] 
+ 0: [
+    ]abcd[
+ 0: ]
+    \\backslash 
+ 0: \
+    *** Failers
+No match
+    -46]789
+No match
+    well
+No match
+    
+/\d\d\/\d\d\/\d\d\d\d/
+    01/01/2000
+ 0: 01/01/2000
+
+/word (?:[a-zA-Z0-9]+ ){0,10}otherword/
+  word cat dog elephant mussel cow horse canary baboon snake shark otherword
+ 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword
+  word cat dog elephant mussel cow horse canary baboon snake shark
+No match
+
+/word (?:[a-zA-Z0-9]+ ){0,300}otherword/
+  word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope
+No match
+
+/^(a){0,0}/
+    bcd
+ 0: 
+    abc
+ 0: 
+    aab     
+ 0: 
+
+/^(a){0,1}/
+    bcd
+ 0: 
+    abc
+ 0: a
+ 1: a
+    aab  
+ 0: a
+ 1: a
+
+/^(a){0,2}/
+    bcd
+ 0: 
+    abc
+ 0: a
+ 1: a
+    aab  
+ 0: aa
+ 1: a
+
+/^(a){0,3}/
+    bcd
+ 0: 
+    abc
+ 0: a
+ 1: a
+    aab
+ 0: aa
+ 1: a
+    aaa   
+ 0: aaa
+ 1: a
+
+/^(a){0,}/
+    bcd
+ 0: 
+    abc
+ 0: a
+ 1: a
+    aab
+ 0: aa
+ 1: a
+    aaa
+ 0: aaa
+ 1: a
+    aaaaaaaa    
+ 0: aaaaaaaa
+ 1: a
+
+/^(a){1,1}/
+    bcd
+No match
+    abc
+ 0: a
+ 1: a
+    aab  
+ 0: a
+ 1: a
+
+/^(a){1,2}/
+    bcd
+No match
+    abc
+ 0: a
+ 1: a
+    aab  
+ 0: aa
+ 1: a
+
+/^(a){1,3}/
+    bcd
+No match
+    abc
+ 0: a
+ 1: a
+    aab
+ 0: aa
+ 1: a
+    aaa   
+ 0: aaa
+ 1: a
+
+/^(a){1,}/
+    bcd
+No match
+    abc
+ 0: a
+ 1: a
+    aab
+ 0: aa
+ 1: a
+    aaa
+ 0: aaa
+ 1: a
+    aaaaaaaa    
+ 0: aaaaaaaa
+ 1: a
+
+/.*\.gif/
+    borfle\nbib.gif\nno
+ 0: bib.gif
+
+/.{0,}\.gif/
+    borfle\nbib.gif\nno
+ 0: bib.gif
+
+/.*\.gif/m
+    borfle\nbib.gif\nno
+ 0: bib.gif
+
+/.*\.gif/s
+    borfle\nbib.gif\nno
+ 0: borfle\x0abib.gif
+
+/.*\.gif/ms
+    borfle\nbib.gif\nno
+ 0: borfle\x0abib.gif
+    
+/.*$/
+    borfle\nbib.gif\nno
+ 0: no
+
+/.*$/m
+    borfle\nbib.gif\nno
+ 0: borfle
+
+/.*$/s
+    borfle\nbib.gif\nno
+ 0: borfle\x0abib.gif\x0ano
+
+/.*$/ms
+    borfle\nbib.gif\nno
+ 0: borfle\x0abib.gif\x0ano
+    
+/.*$/
+    borfle\nbib.gif\nno\n
+ 0: no
+
+/.*$/m
+    borfle\nbib.gif\nno\n
+ 0: borfle
+
+/.*$/s
+    borfle\nbib.gif\nno\n
+ 0: borfle\x0abib.gif\x0ano\x0a
+
+/.*$/ms
+    borfle\nbib.gif\nno\n
+ 0: borfle\x0abib.gif\x0ano\x0a
+    
+/(.*X|^B)/
+    abcde\n1234Xyz
+ 0: 1234X
+ 1: 1234X
+    BarFoo 
+ 0: B
+ 1: B
+    *** Failers
+No match
+    abcde\nBar  
+No match
+
+/(.*X|^B)/m
+    abcde\n1234Xyz
+ 0: 1234X
+ 1: 1234X
+    BarFoo 
+ 0: B
+ 1: B
+    abcde\nBar  
+ 0: B
+ 1: B
+
+/(.*X|^B)/s
+    abcde\n1234Xyz
+ 0: abcde\x0a1234X
+ 1: abcde\x0a1234X
+    BarFoo 
+ 0: B
+ 1: B
+    *** Failers
+No match
+    abcde\nBar  
+No match
+
+/(.*X|^B)/ms
+    abcde\n1234Xyz
+ 0: abcde\x0a1234X
+ 1: abcde\x0a1234X
+    BarFoo 
+ 0: B
+ 1: B
+    abcde\nBar  
+ 0: B
+ 1: B
+
+/(?s)(.*X|^B)/
+    abcde\n1234Xyz
+ 0: abcde\x0a1234X
+ 1: abcde\x0a1234X
+    BarFoo 
+ 0: B
+ 1: B
+    *** Failers 
+No match
+    abcde\nBar  
+No match
+
+/(?s:.*X|^B)/
+    abcde\n1234Xyz
+ 0: abcde\x0a1234X
+    BarFoo 
+ 0: B
+    *** Failers 
+No match
+    abcde\nBar  
+No match
+
+/^.*B/
+    **** Failers
+No match
+    abc\nB
+No match
+     
+/(?s)^.*B/
+    abc\nB
+ 0: abc\x0aB
+
+/(?m)^.*B/
+    abc\nB
+ 0: B
+     
+/(?ms)^.*B/
+    abc\nB
+ 0: abc\x0aB
+
+/(?ms)^B/
+    abc\nB
+ 0: B
+
+/(?s)B$/
+    B\n
+ 0: B
+
+/^[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]/
+    123456654321
+ 0: 123456654321
+  
+/^\d\d\d\d\d\d\d\d\d\d\d\d/
+    123456654321 
+ 0: 123456654321
+
+/^[\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d][\d]/
+    123456654321
+ 0: 123456654321
+  
+/^[abc]{12}/
+    abcabcabcabc
+ 0: abcabcabcabc
+    
+/^[a-c]{12}/
+    abcabcabcabc
+ 0: abcabcabcabc
+    
+/^(a|b|c){12}/
+    abcabcabcabc 
+ 0: abcabcabcabc
+ 1: c
+
+/^[abcdefghijklmnopqrstuvwxy0123456789]/
+    n
+ 0: n
+    *** Failers 
+No match
+    z 
+No match
+
+/abcde{0,0}/
+    abcd
+ 0: abcd
+    *** Failers
+No match
+    abce  
+No match
+
+/ab[cd]{0,0}e/
+    abe
+ 0: abe
+    *** Failers
+No match
+    abcde 
+No match
+    
+/ab(c){0,0}d/
+    abd
+ 0: abd
+    *** Failers
+No match
+    abcd   
+No match
+
+/a(b*)/
+    a
+ 0: a
+ 1: 
+    ab
+ 0: ab
+ 1: b
+    abbbb
+ 0: abbbb
+ 1: bbbb
+    *** Failers
+ 0: a
+ 1: 
+    bbbbb    
+No match
+    
+/ab\d{0}e/
+    abe
+ 0: abe
+    *** Failers
+No match
+    ab1e   
+No match
+    
+/"([^\\"]+|\\.)*"/
+    the \"quick\" brown fox
+ 0: "quick"
+ 1: quick
+    \"the \\\"quick\\\" brown fox\" 
+ 0: "the \"quick\" brown fox"
+ 1:  brown fox
+
+/.*?/g+
+    abc
+ 0: 
+ 0+ abc
+ 0: a
+ 0+ bc
+ 0: 
+ 0+ bc
+ 0: b
+ 0+ c
+ 0: 
+ 0+ c
+ 0: c
+ 0+ 
+ 0: 
+ 0+ 
+  
+/\b/g+
+    abc 
+ 0: 
+ 0+ abc
+ 0: 
+ 0+ 
+
+/\b/+g
+    abc 
+ 0: 
+ 0+ abc
+ 0: 
+ 0+ 
+
+//g
+    abc
+ 0: 
+ 0: 
+ 0: 
+ 0: 
+
+/ End of test input /
+
diff --git a/ext/pcre/pcrelib/testdata/testoutput2 b/ext/pcre/pcrelib/testdata/testoutput2
new file mode 100644 (file)
index 0000000..d0fc036
--- /dev/null
@@ -0,0 +1,2072 @@
+PCRE version 3.1 09-Feb-2000
+
+/(a)b|/
+Capturing subpattern count = 1
+No options
+No first char
+No need char
+
+/abc/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'c'
+    abc
+ 0: abc
+    defabc
+ 0: abc
+    \Aabc
+ 0: abc
+    *** Failers
+No match
+    \Adefabc
+No match
+    ABC
+No match
+
+/^abc/
+Capturing subpattern count = 0
+Options: anchored
+No first char
+Need char = 'c'
+    abc
+ 0: abc
+    \Aabc
+ 0: abc
+    *** Failers
+No match
+    defabc
+No match
+    \Adefabc
+No match
+
+/a+bc/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'c'
+
+/a*bc/
+Capturing subpattern count = 0
+No options
+No first char
+Need char = 'c'
+
+/a{3}bc/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'c'
+
+/(abc|a+z)/
+Capturing subpattern count = 1
+No options
+First char = 'a'
+No need char
+
+/^abc$/
+Capturing subpattern count = 0
+Options: anchored
+No first char
+Need char = 'c'
+    abc
+ 0: abc
+    *** Failers
+No match
+    def\nabc
+No match
+
+/ab\gdef/X
+Failed: unrecognized character follows \ at offset 3
+
+/(?X)ab\gdef/X
+Failed: unrecognized character follows \ at offset 7
+
+/x{5,4}/
+Failed: numbers out of order in {} quantifier at offset 5
+
+/z{65536}/
+Failed: number too big in {} quantifier at offset 7
+
+/[abcd/
+Failed: missing terminating ] for character class at offset 5
+
+/[\B]/
+Failed: invalid escape sequence in character class at offset 2
+
+/[a-\w]/
+Failed: invalid escape sequence in character class at offset 4
+
+/[z-a]/
+Failed: range out of order in character class at offset 3
+
+/^*/
+Failed: nothing to repeat at offset 1
+
+/(abc/
+Failed: missing ) at offset 4
+
+/(?# abc/
+Failed: missing ) after comment at offset 7
+
+/(?z)abc/
+Failed: unrecognized character after (? at offset 2
+
+/.*b/
+Capturing subpattern count = 0
+No options
+First char at start or follows \n
+Need char = 'b'
+
+/.*?b/
+Capturing subpattern count = 0
+No options
+First char at start or follows \n
+Need char = 'b'
+
+/cat|dog|elephant/
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+    this sentence eventually mentions a cat
+ 0: cat
+    this sentences rambles on and on for a while and then reaches elephant
+ 0: elephant
+
+/cat|dog|elephant/S
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Starting character set: c d e 
+    this sentence eventually mentions a cat
+ 0: cat
+    this sentences rambles on and on for a while and then reaches elephant
+ 0: elephant
+
+/cat|dog|elephant/iS
+Capturing subpattern count = 0
+Options: caseless
+No first char
+No need char
+Starting character set: C D E c d e 
+    this sentence eventually mentions a CAT cat
+ 0: CAT
+    this sentences rambles on and on for a while to elephant ElePhant
+ 0: elephant
+
+/a|[bcd]/S
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Starting character set: a b c d 
+
+/(a|[^\dZ])/S
+Capturing subpattern count = 1
+No options
+No first char
+No need char
+Starting character set: \x00 \x01 \x02 \x03 \x04 \x05 \x06 \x07 \x08 \x09 \x0a 
+  \x0b \x0c \x0d \x0e \x0f \x10 \x11 \x12 \x13 \x14 \x15 \x16 \x17 \x18 \x19 
+  \x1a \x1b \x1c \x1d \x1e \x1f \x20 ! " # $ % & ' ( ) * + , - . / : ; < = > 
+  ? @ A B C D E F G H I J K L M N O P Q R S T U V W X Y [ \ ] ^ _ ` a b c d 
+  e f g h i j k l m n o p q r s t u v w x y z { | } ~ \x7f \x80 \x81 \x82 \x83 
+  \x84 \x85 \x86 \x87 \x88 \x89 \x8a \x8b \x8c \x8d \x8e \x8f \x90 \x91 \x92 
+  \x93 \x94 \x95 \x96 \x97 \x98 \x99 \x9a \x9b \x9c \x9d \x9e \x9f \xa0 \xa1 
+  \xa2 \xa3 \xa4 \xa5 \xa6 \xa7 \xa8 \xa9 \xaa \xab \xac \xad \xae \xaf \xb0 
+  \xb1 \xb2 \xb3 \xb4 \xb5 \xb6 \xb7 \xb8 \xb9 \xba \xbb \xbc \xbd \xbe \xbf 
+  \xc0 \xc1 \xc2 \xc3 \xc4 \xc5 \xc6 \xc7 \xc8 \xc9 \xca \xcb \xcc \xcd \xce 
+  \xcf \xd0 \xd1 \xd2 \xd3 \xd4 \xd5 \xd6 \xd7 \xd8 \xd9 \xda \xdb \xdc \xdd 
+  \xde \xdf \xe0 \xe1 \xe2 \xe3 \xe4 \xe5 \xe6 \xe7 \xe8 \xe9 \xea \xeb \xec 
+  \xed \xee \xef \xf0 \xf1 \xf2 \xf3 \xf4 \xf5 \xf6 \xf7 \xf8 \xf9 \xfa \xfb 
+  \xfc \xfd \xfe \xff 
+
+/(a|b)*[\s]/S
+Capturing subpattern count = 1
+No options
+No first char
+No need char
+Starting character set: \x09 \x0a \x0b \x0c \x0d \x20 a b 
+
+/(ab\2)/
+Failed: back reference to non-existent subpattern at offset 6
+
+/{4,5}abc/
+Failed: nothing to repeat at offset 4
+
+/(a)(b)(c)\2/
+Capturing subpattern count = 3
+Max back reference = 2
+No options
+First char = 'a'
+Need char = 'c'
+    abcb
+ 0: abcb
+ 1: a
+ 2: b
+ 3: c
+    \O0abcb
+Matched, but too many substrings
+    \O3abcb
+Matched, but too many substrings
+ 0: abcb
+    \O6abcb
+Matched, but too many substrings
+ 0: abcb
+ 1: a
+    \O9abcb
+Matched, but too many substrings
+ 0: abcb
+ 1: a
+ 2: b
+    \O12abcb 
+ 0: abcb
+ 1: a
+ 2: b
+ 3: c
+
+/(a)bc|(a)(b)\2/
+Capturing subpattern count = 3
+Max back reference = 2
+No options
+First char = 'a'
+No need char
+    abc
+ 0: abc
+ 1: a
+    \O0abc
+Matched, but too many substrings
+    \O3abc
+Matched, but too many substrings
+ 0: abc
+    \O6abc
+ 0: abc
+ 1: a
+    aba
+ 0: aba
+ 1: <unset>
+ 2: a
+ 3: b
+    \O0aba
+Matched, but too many substrings
+    \O3aba
+Matched, but too many substrings
+ 0: aba
+    \O6aba
+Matched, but too many substrings
+ 0: aba
+ 1: <unset>
+    \O9aba
+Matched, but too many substrings
+ 0: aba
+ 1: <unset>
+ 2: a
+    \O12aba
+ 0: aba
+ 1: <unset>
+ 2: a
+ 3: b
+
+/abc$/E
+Capturing subpattern count = 0
+Options: dollar_endonly
+First char = 'a'
+Need char = 'c'
+    abc
+ 0: abc
+    *** Failers
+No match
+    abc\n
+No match
+    abc\ndef
+No match
+
+/(a)(b)(c)(d)(e)\6/
+Failed: back reference to non-existent subpattern at offset 17
+
+/the quick brown fox/
+Capturing subpattern count = 0
+No options
+First char = 't'
+Need char = 'x'
+    the quick brown fox
+ 0: the quick brown fox
+    this is a line with the quick brown fox
+ 0: the quick brown fox
+
+/the quick brown fox/A
+Capturing subpattern count = 0
+Options: anchored
+No first char
+Need char = 'x'
+    the quick brown fox
+ 0: the quick brown fox
+    *** Failers
+No match
+    this is a line with the quick brown fox
+No match
+
+/ab(?z)cd/
+Failed: unrecognized character after (? at offset 4
+
+/^abc|def/
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+    abcdef
+ 0: abc
+    abcdef\B
+ 0: def
+
+/.*((abc)$|(def))/
+Capturing subpattern count = 3
+No options
+First char at start or follows \n
+No need char
+    defabc
+ 0: defabc
+ 1: abc
+ 2: abc
+    \Zdefabc
+ 0: def
+ 1: def
+ 2: <unset>
+ 3: def
+
+/abc/P
+    abc
+ 0: abc
+    *** Failers
+No match: POSIX code 17: match failed
+    
+/^abc|def/P
+    abcdef
+ 0: abc
+    abcdef\B
+ 0: def
+
+/.*((abc)$|(def))/P
+    defabc
+ 0: defabc
+ 1: abc
+ 2: abc
+    \Zdefabc
+ 0: def
+ 1: def
+ 3: def
+  
+/the quick brown fox/P
+    the quick brown fox
+ 0: the quick brown fox
+    *** Failers 
+No match: POSIX code 17: match failed
+    The Quick Brown Fox 
+No match: POSIX code 17: match failed
+
+/the quick brown fox/Pi
+    the quick brown fox
+ 0: the quick brown fox
+    The Quick Brown Fox 
+ 0: The Quick Brown Fox
+
+/abc.def/P
+    *** Failers
+No match: POSIX code 17: match failed
+    abc\ndef
+No match: POSIX code 17: match failed
+    
+/abc$/P
+    abc
+ 0: abc
+    abc\n 
+ 0: abc
+
+/(abc)\2/P
+Failed: POSIX code 15: bad back reference at offset 7     
+
+/(abc\1)/P
+    abc
+No match: POSIX code 17: match failed
+
+/)/
+Failed: unmatched parentheses at offset 0
+
+/a[]b/
+Failed: missing terminating ] for character class at offset 4
+
+/[^aeiou ]{3,}/
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+    co-processors, and for 
+ 0: -pr
+    
+/<.*>/
+Capturing subpattern count = 0
+No options
+First char = '<'
+Need char = '>'
+    abc<def>ghi<klm>nop
+ 0: <def>ghi<klm>
+
+/<.*?>/
+Capturing subpattern count = 0
+No options
+First char = '<'
+Need char = '>'
+    abc<def>ghi<klm>nop
+ 0: <def>
+
+/<.*>/U
+Capturing subpattern count = 0
+Options: ungreedy
+First char = '<'
+Need char = '>'
+    abc<def>ghi<klm>nop
+ 0: <def>
+    
+/<.*>(?U)/
+Capturing subpattern count = 0
+Options: ungreedy
+First char = '<'
+Need char = '>'
+    abc<def>ghi<klm>nop
+ 0: <def>
+
+/<.*?>/U
+Capturing subpattern count = 0
+Options: ungreedy
+First char = '<'
+Need char = '>'
+    abc<def>ghi<klm>nop
+ 0: <def>ghi<klm>
+    
+/={3,}/U
+Capturing subpattern count = 0
+Options: ungreedy
+First char = '='
+Need char = '='
+    abc========def
+ 0: ===
+    
+/(?U)={3,}?/
+Capturing subpattern count = 0
+Options: ungreedy
+First char = '='
+Need char = '='
+    abc========def
+ 0: ========
+    
+/(?<!bar|cattle)foo/
+Capturing subpattern count = 0
+No options
+First char = 'f'
+Need char = 'o'
+    foo
+ 0: foo
+    catfoo 
+ 0: foo
+    *** Failers
+No match
+    the barfoo
+No match
+    and cattlefoo   
+No match
+
+/(?<=a+)b/
+Failed: lookbehind assertion is not fixed length at offset 6
+
+/(?<=aaa|b{0,3})b/
+Failed: lookbehind assertion is not fixed length at offset 14
+
+/(?<!(foo)a\1)bar/
+Failed: lookbehind assertion is not fixed length at offset 12
+
+/(?i)abc/
+Capturing subpattern count = 0
+Options: caseless
+First char = 'a'
+Need char = 'c'
+
+/(a|(?m)a)/
+Capturing subpattern count = 1
+No options
+First char = 'a'
+No need char
+
+/(?i)^1234/
+Capturing subpattern count = 0
+Options: anchored caseless
+No first char
+Need char = '4'
+
+/(^b|(?i)^d)/
+Capturing subpattern count = 1
+Options: anchored
+Case state changes
+No first char
+No need char
+
+/(?s).*/
+Capturing subpattern count = 0
+Options: anchored dotall
+No first char
+No need char
+
+/[abcd]/S
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Starting character set: a b c d 
+
+/(?i)[abcd]/S
+Capturing subpattern count = 0
+Options: caseless
+No first char
+No need char
+Starting character set: A B C D a b c d 
+
+/(?m)[xy]|(b|c)/S
+Capturing subpattern count = 1
+Options: multiline
+No first char
+No need char
+Starting character set: b c x y 
+
+/(^a|^b)/m
+Capturing subpattern count = 1
+Options: multiline
+First char at start or follows \n
+No need char
+
+/(?i)(^a|^b)/m
+Capturing subpattern count = 1
+Options: caseless multiline
+First char at start or follows \n
+No need char
+
+/(a)(?(1)a|b|c)/
+Failed: conditional group contains more than two branches at offset 13
+
+/(?(?=a)a|b|c)/
+Failed: conditional group contains more than two branches at offset 12
+
+/(?(1a)/
+Failed: malformed number after (?( at offset 4
+
+/(?(?i))/
+Failed: assertion expected after (?( at offset 3
+
+/(?(abc))/
+Failed: assertion expected after (?( at offset 3
+
+/(?(?<ab))/
+Failed: unrecognized character after (?< at offset 2
+
+/((?s)blah)\s+\1/
+Capturing subpattern count = 1
+Max back reference = 1
+No options
+First char = 'b'
+Need char = 'h'
+
+/((?i)blah)\s+\1/
+Capturing subpattern count = 1
+Max back reference = 1
+No options
+Case state changes
+No first char
+Need char = 'h'
+
+/((?i)b)/DS
+------------------------------------------------------------------
+  0  16 Bra 0
+  3   8 Bra 1
+  6  01 Opt
+  8   1 b
+ 11   8 Ket
+ 14  00 Opt
+ 16  16 Ket
+ 19     End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+No options
+Case state changes
+No first char
+Need char = 'b'
+Starting character set: B b 
+
+/(a*b|(?i:c*(?-i)d))/S
+Capturing subpattern count = 1
+No options
+Case state changes
+No first char
+No need char
+Starting character set: C a b c d 
+
+/a$/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+No need char
+    a
+ 0: a
+    a\n
+ 0: a
+    *** Failers 
+No match
+    \Za
+No match
+    \Za\n   
+No match
+
+/a$/m
+Capturing subpattern count = 0
+Options: multiline
+First char = 'a'
+No need char
+    a
+ 0: a
+    a\n
+ 0: a
+    \Za\n   
+ 0: a
+    *** Failers 
+No match
+    \Za
+No match
+    
+/\Aabc/m
+Capturing subpattern count = 0
+Options: anchored multiline
+No first char
+Need char = 'c'
+
+/^abc/m 
+Capturing subpattern count = 0
+Options: multiline
+First char at start or follows \n
+Need char = 'c'
+
+/^((a+)(?U)([ab]+)(?-U)([bc]+)(\w*))/
+Capturing subpattern count = 5
+Options: anchored
+No first char
+Need char = 'a'
+  aaaaabbbbbcccccdef
+ 0: aaaaabbbbbcccccdef
+ 1: aaaaabbbbbcccccdef
+ 2: aaaaa
+ 3: b
+ 4: bbbbccccc
+ 5: def
+
+/(?<=foo)[ab]/S
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Starting character set: a b 
+
+/(?<!foo)(alpha|omega)/S
+Capturing subpattern count = 1
+No options
+No first char
+Need char = 'a'
+Starting character set: a o 
+
+/(?!alphabet)[ab]/S
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Starting character set: a b 
+
+/(?<=foo\n)^bar/m
+Capturing subpattern count = 0
+Options: multiline
+First char at start or follows \n
+Need char = 'r'
+
+/(?>^abc)/m
+Capturing subpattern count = 0
+Options: multiline
+First char at start or follows \n
+Need char = 'c'
+    abc
+ 0: abc
+    def\nabc
+ 0: abc
+    *** Failers
+No match
+    defabc   
+No match
+
+/(?<=ab(c+)d)ef/
+Failed: lookbehind assertion is not fixed length at offset 11
+
+/(?<=ab(?<=c+)d)ef/
+Failed: lookbehind assertion is not fixed length at offset 12
+
+/(?<=ab(c|de)f)g/
+Failed: lookbehind assertion is not fixed length at offset 13
+
+/The next three are in testinput2 because they have variable length branches/
+Capturing subpattern count = 0
+No options
+First char = 'T'
+Need char = 's'
+
+/(?<=bullock|donkey)-cart/
+Capturing subpattern count = 0
+No options
+First char = '-'
+Need char = 't'
+    the bullock-cart
+ 0: -cart
+    a donkey-cart race
+ 0: -cart
+    *** Failers
+No match
+    cart
+No match
+    horse-and-cart    
+No match
+      
+/(?<=ab(?i)x|y|z)/
+Capturing subpattern count = 0
+No options
+Case state changes
+No first char
+No need char
+
+/(?>.*)(?<=(abcd)|(xyz))/
+Capturing subpattern count = 2
+No options
+First char at start or follows \n
+No need char
+    alphabetabcd
+ 0: alphabetabcd
+ 1: abcd
+    endingxyz
+ 0: endingxyz
+ 1: <unset>
+ 2: xyz
+
+/(?<=ab(?i)x(?-i)y|(?i)z|b)ZZ/
+Capturing subpattern count = 0
+No options
+Case state changes
+First char = 'Z'
+Need char = 'Z'
+    abxyZZ
+ 0: ZZ
+    abXyZZ
+ 0: ZZ
+    ZZZ
+ 0: ZZ
+    zZZ
+ 0: ZZ
+    bZZ
+ 0: ZZ
+    BZZ     
+ 0: ZZ
+    *** Failers
+No match
+    ZZ 
+No match
+    abXYZZ 
+No match
+    zzz
+No match
+    bzz  
+No match
+
+/(?<!(foo)a)bar/
+Capturing subpattern count = 1
+No options
+First char = 'b'
+Need char = 'r'
+    bar
+ 0: bar
+    foobbar 
+ 0: bar
+    *** Failers
+No match
+    fooabar  
+No match
+
+/This one is here because Perl 5.005_02 doesn't fail it/
+Capturing subpattern count = 0
+No options
+First char = 'T'
+Need char = 't'
+
+/^(a)?(?(1)a|b)+$/
+Capturing subpattern count = 1
+Options: anchored
+No first char
+No need char
+    *** Failers
+No match
+    a 
+No match
+
+/This one is here because I think Perl 5.005_02 gets the setting of $1 wrong/
+Capturing subpattern count = 0
+No options
+First char = 'T'
+Need char = 'g'
+
+/^(a\1?){4}$/
+Capturing subpattern count = 1
+Max back reference = 1
+Options: anchored
+No first char
+Need char = 'a'
+    aaaaaa
+ 0: aaaaaa
+ 1: aa
+    
+/These are syntax tests from Perl 5.005/
+Capturing subpattern count = 0
+No options
+First char = 'T'
+Need char = '5'
+
+/a[b-a]/
+Failed: range out of order in character class at offset 4
+
+/a[]b/
+Failed: missing terminating ] for character class at offset 4
+
+/a[/
+Failed: missing terminating ] for character class at offset 2
+
+/*a/
+Failed: nothing to repeat at offset 0
+
+/(*)b/
+Failed: nothing to repeat at offset 1
+
+/abc)/
+Failed: unmatched parentheses at offset 3
+
+/(abc/
+Failed: missing ) at offset 4
+
+/a**/
+Failed: nothing to repeat at offset 2
+
+/)(/
+Failed: unmatched parentheses at offset 0
+
+/\1/
+Failed: back reference to non-existent subpattern at offset 2
+
+/\2/
+Failed: back reference to non-existent subpattern at offset 2
+
+/(a)|\2/
+Failed: back reference to non-existent subpattern at offset 6
+
+/a[b-a]/i
+Failed: range out of order in character class at offset 4
+
+/a[]b/i
+Failed: missing terminating ] for character class at offset 4
+
+/a[/i
+Failed: missing terminating ] for character class at offset 2
+
+/*a/i
+Failed: nothing to repeat at offset 0
+
+/(*)b/i
+Failed: nothing to repeat at offset 1
+
+/abc)/i
+Failed: unmatched parentheses at offset 3
+
+/(abc/i
+Failed: missing ) at offset 4
+
+/a**/i
+Failed: nothing to repeat at offset 2
+
+/)(/i
+Failed: unmatched parentheses at offset 0
+
+/:(?:/
+Failed: missing ) at offset 4
+
+/(?<%)b/
+Failed: unrecognized character after (?< at offset 0
+
+/a(?{)b/
+Failed: unrecognized character after (? at offset 3
+
+/a(?{{})b/
+Failed: unrecognized character after (? at offset 3
+
+/a(?{}})b/
+Failed: unrecognized character after (? at offset 3
+
+/a(?{"{"})b/
+Failed: unrecognized character after (? at offset 3
+
+/a(?{"{"}})b/
+Failed: unrecognized character after (? at offset 3
+
+/(?(1?)a|b)/
+Failed: malformed number after (?( at offset 4
+
+/(?(1)a|b|c)/
+Failed: conditional group contains more than two branches at offset 10
+
+/[a[:xyz:/
+Failed: missing terminating ] for character class at offset 8
+
+/(?<=x+)y/
+Failed: lookbehind assertion is not fixed length at offset 6
+
+/a{37,17}/
+Failed: numbers out of order in {} quantifier at offset 7
+
+/abc/\
+Failed: \ at end of pattern at offset 4
+
+/abc/\P
+Failed: POSIX code 9: bad escape sequence at offset 4     
+
+/abc/\i
+Failed: \ at end of pattern at offset 4
+
+/(a)bc(d)/
+Capturing subpattern count = 2
+No options
+First char = 'a'
+Need char = 'd'
+    abcd
+ 0: abcd
+ 1: a
+ 2: d
+    abcd\C2
+ 0: abcd
+ 1: a
+ 2: d
+ 2C d (1)
+    abcd\C5
+ 0: abcd
+ 1: a
+ 2: d
+copy substring 5 failed -7
+     
+/(.{20})/
+Capturing subpattern count = 1
+No options
+No first char
+No need char
+    abcdefghijklmnopqrstuvwxyz
+ 0: abcdefghijklmnopqrst
+ 1: abcdefghijklmnopqrst
+    abcdefghijklmnopqrstuvwxyz\C1
+ 0: abcdefghijklmnopqrst
+ 1: abcdefghijklmnopqrst
+copy substring 1 failed -6
+    abcdefghijklmnopqrstuvwxyz\G1
+ 0: abcdefghijklmnopqrst
+ 1: abcdefghijklmnopqrst
+ 1G abcdefghijklmnopqrst (20)
+     
+/(.{15})/
+Capturing subpattern count = 1
+No options
+No first char
+No need char
+    abcdefghijklmnopqrstuvwxyz
+ 0: abcdefghijklmno
+ 1: abcdefghijklmno
+    abcdefghijklmnopqrstuvwxyz\C1\G1
+ 0: abcdefghijklmno
+ 1: abcdefghijklmno
+ 1C abcdefghijklmno (15)
+ 1G abcdefghijklmno (15)
+
+/(.{16})/
+Capturing subpattern count = 1
+No options
+No first char
+No need char
+    abcdefghijklmnopqrstuvwxyz
+ 0: abcdefghijklmnop
+ 1: abcdefghijklmnop
+    abcdefghijklmnopqrstuvwxyz\C1\G1\L
+ 0: abcdefghijklmnop
+ 1: abcdefghijklmnop
+copy substring 1 failed -6
+ 1G abcdefghijklmnop (16)
+ 0L abcdefghijklmnop
+ 1L abcdefghijklmnop
+    
+/^(a|(bc))de(f)/
+Capturing subpattern count = 3
+Options: anchored
+No first char
+Need char = 'f'
+    adef\G1\G2\G3\G4\L 
+ 0: adef
+ 1: a
+ 2: <unset>
+ 3: f
+ 1G a (1)
+ 2G  (0)
+ 3G f (1)
+get substring 4 failed -7
+ 0L adef
+ 1L a
+ 2L 
+ 3L f
+    bcdef\G1\G2\G3\G4\L 
+ 0: bcdef
+ 1: bc
+ 2: bc
+ 3: f
+ 1G bc (2)
+ 2G bc (2)
+ 3G f (1)
+get substring 4 failed -7
+ 0L bcdef
+ 1L bc
+ 2L bc
+ 3L f
+    adefghijk\C0 
+ 0: adef
+ 1: a
+ 2: <unset>
+ 3: f
+ 0C adef (4)
+    
+/^abc\00def/
+Capturing subpattern count = 0
+Options: anchored
+No first char
+Need char = 'f'
+    abc\00def\L\C0 
+ 0: abc\x00def
+ 0C abc (7)
+ 0L abc
+    
+/word ((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ 
+)((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ )((?:[a-zA-Z0-9]+ 
+)?)?)?)?)?)?)?)?)?otherword/M
+Memory allocation (code space): 428
+Capturing subpattern count = 8
+No options
+First char = 'w'
+Need char = 'd'
+
+/.*X/D
+------------------------------------------------------------------
+  0   8 Bra 0
+  3     Any*
+  5   1 X
+  8   8 Ket
+ 11     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+First char at start or follows \n
+Need char = 'X'
+
+/.*X/Ds
+------------------------------------------------------------------
+  0   8 Bra 0
+  3     Any*
+  5   1 X
+  8   8 Ket
+ 11     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored dotall
+No first char
+Need char = 'X'
+
+/(.*X|^B)/D
+------------------------------------------------------------------
+  0  21 Bra 0
+  3   8 Bra 1
+  6     Any*
+  8   1 X
+ 11   7 Alt
+ 14     ^
+ 15   1 B
+ 18  15 Ket
+ 21  21 Ket
+ 24     End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+No options
+First char at start or follows \n
+No need char
+
+/(.*X|^B)/Ds
+------------------------------------------------------------------
+  0  21 Bra 0
+  3   8 Bra 1
+  6     Any*
+  8   1 X
+ 11   7 Alt
+ 14     ^
+ 15   1 B
+ 18  15 Ket
+ 21  21 Ket
+ 24     End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: anchored dotall
+No first char
+No need char
+    
+/(?s)(.*X|^B)/D
+------------------------------------------------------------------
+  0  21 Bra 0
+  3   8 Bra 1
+  6     Any*
+  8   1 X
+ 11   7 Alt
+ 14     ^
+ 15   1 B
+ 18  15 Ket
+ 21  21 Ket
+ 24     End
+------------------------------------------------------------------
+Capturing subpattern count = 1
+Options: anchored dotall
+No first char
+No need char
+
+/(?s:.*X|^B)/D
+------------------------------------------------------------------
+  0  27 Bra 0
+  3  10 Bra 0
+  6  04 Opt
+  8     Any*
+ 10   1 X
+ 13   9 Alt
+ 16  04 Opt
+ 18     ^
+ 19   1 B
+ 22  19 Ket
+ 25  00 Opt
+ 27  27 Ket
+ 30     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+First char at start or follows \n
+No need char
+
+/\Biss\B/+
+Capturing subpattern count = 0
+No options
+First char = 'i'
+Need char = 's'
+    Mississippi
+ 0: iss
+ 0+ issippi
+
+/\Biss\B/+P
+    Mississippi
+ 0: iss
+ 0+ issippi
+
+/iss/G+
+Capturing subpattern count = 0
+No options
+First char = 'i'
+Need char = 's'
+    Mississippi
+ 0: iss
+ 0+ issippi
+ 0: iss
+ 0+ ippi
+
+/\Biss\B/G+
+Capturing subpattern count = 0
+No options
+First char = 'i'
+Need char = 's'
+    Mississippi
+ 0: iss
+ 0+ issippi
+
+/\Biss\B/g+
+Capturing subpattern count = 0
+No options
+First char = 'i'
+Need char = 's'
+    Mississippi
+ 0: iss
+ 0+ issippi
+ 0: iss
+ 0+ ippi
+    *** Failers
+No match
+    Mississippi\A
+No match
+
+/(?<=[Ms])iss/g+
+Capturing subpattern count = 0
+No options
+First char = 'i'
+Need char = 's'
+    Mississippi
+ 0: iss
+ 0+ issippi
+ 0: iss
+ 0+ ippi
+
+/(?<=[Ms])iss/G+
+Capturing subpattern count = 0
+No options
+First char = 'i'
+Need char = 's'
+    Mississippi
+ 0: iss
+ 0+ issippi
+
+/^iss/g+
+Capturing subpattern count = 0
+Options: anchored
+No first char
+Need char = 's'
+    ississippi
+ 0: iss
+ 0+ issippi
+    
+/.*iss/g+
+Capturing subpattern count = 0
+No options
+First char at start or follows \n
+Need char = 's'
+    abciss\nxyzisspqr 
+ 0: abciss
+ 0+ \x0axyzisspqr
+ 0: xyziss
+ 0+ pqr
+
+/.i./+g
+Capturing subpattern count = 0
+No options
+No first char
+Need char = 'i'
+    Mississippi
+ 0: Mis
+ 0+ sissippi
+ 0: sis
+ 0+ sippi
+ 0: sip
+ 0+ pi
+    Mississippi\A
+ 0: Mis
+ 0+ sissippi
+ 0: sis
+ 0+ sippi
+ 0: sip
+ 0+ pi
+    Missouri river
+ 0: Mis
+ 0+ souri river
+ 0: ri 
+ 0+ river
+ 0: riv
+ 0+ er
+    Missouri river\A  
+ 0: Mis
+ 0+ souri river
+
+/^.is/+g
+Capturing subpattern count = 0
+Options: anchored
+No first char
+Need char = 's'
+    Mississippi
+ 0: Mis
+ 0+ sissippi
+
+/^ab\n/g+
+Capturing subpattern count = 0
+Options: anchored
+No first char
+Need char = 10
+    ab\nab\ncd
+ 0: ab\x0a
+ 0+ ab\x0acd
+
+/^ab\n/mg+
+Capturing subpattern count = 0
+Options: multiline
+First char at start or follows \n
+Need char = 10
+    ab\nab\ncd
+ 0: ab\x0a
+ 0+ ab\x0acd
+ 0: ab\x0a
+ 0+ cd
+
+/abc/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'c'
+
+/abc|bac/
+Capturing subpattern count = 0
+No options
+No first char
+Need char = 'c'
+
+/(abc|bac)/
+Capturing subpattern count = 1
+No options
+No first char
+Need char = 'c'
+
+/(abc|(c|dc))/
+Capturing subpattern count = 2
+No options
+No first char
+Need char = 'c'
+
+/(abc|(d|de)c)/
+Capturing subpattern count = 2
+No options
+No first char
+Need char = 'c'
+
+/a*/
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+
+/a+/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+No need char
+
+/(baa|a+)/
+Capturing subpattern count = 1
+No options
+No first char
+Need char = 'a'
+
+/a{0,3}/
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+
+/baa{3,}/
+Capturing subpattern count = 0
+No options
+First char = 'b'
+Need char = 'a'
+
+/"([^\\"]+|\\.)*"/
+Capturing subpattern count = 1
+No options
+First char = '"'
+Need char = '"'
+
+/(abc|ab[cd])/
+Capturing subpattern count = 1
+No options
+First char = 'a'
+No need char
+
+/(a|.)/
+Capturing subpattern count = 1
+No options
+No first char
+No need char
+
+/a|ba|\w/
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+
+/abc(?=pqr)/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'r'
+
+/...(?<=abc)/
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+
+/abc(?!pqr)/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'c'
+
+/ab./
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'b'
+
+/ab[xyz]/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'b'
+
+/abc*/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'b'
+
+/ab.c*/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'b'
+
+/a.c*/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+No need char
+
+/.c*/
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+
+/ac*/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+No need char
+
+/(a.c*|b.c*)/
+Capturing subpattern count = 1
+No options
+No first char
+No need char
+
+/a.c*|aba/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+No need char
+
+/.+a/
+Capturing subpattern count = 0
+No options
+No first char
+Need char = 'a'
+
+/(?=abcda)a.*/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+No need char
+
+/(?=a)a.*/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+No need char
+
+/a(b)*/
+Capturing subpattern count = 1
+No options
+First char = 'a'
+No need char
+
+/a\d*/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+No need char
+
+/ab\d*/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'b'
+
+/a(\d)*/
+Capturing subpattern count = 1
+No options
+First char = 'a'
+No need char
+
+/abcde{0,0}/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'd'
+
+/ab\d+/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'b'
+
+/a(?(1)b)/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+No need char
+
+/a(?(1)bag|big)/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'g'
+
+/a(?(1)bag|big)*/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+No need char
+
+/a(?(1)bag|big)+/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'g'
+
+/a(?(1)b..|b..)/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'b'
+
+/ab\d{0}e/
+Capturing subpattern count = 0
+No options
+First char = 'a'
+Need char = 'e'
+
+/a?b?/
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+    a
+ 0: a
+    b
+ 0: b
+    ab
+ 0: ab
+    \
+ 0: 
+    *** Failers
+ 0: 
+    \N     
+No match
+    
+/|-/
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+    abcd
+ 0: 
+    -abc
+ 0: 
+    \Nab-c
+ 0: -
+    *** Failers
+ 0: 
+    \Nabc     
+No match
+
+/a*(b+)(z)(z)/P
+    aaaabbbbzzzz
+ 0: aaaabbbbzz
+ 1: bbbb
+ 2: z
+ 3: z
+    aaaabbbbzzzz\O0
+    aaaabbbbzzzz\O1
+ 0: aaaabbbbzz
+    aaaabbbbzzzz\O2
+ 0: aaaabbbbzz
+ 1: bbbb
+    aaaabbbbzzzz\O3
+ 0: aaaabbbbzz
+ 1: bbbb
+ 2: z
+    aaaabbbbzzzz\O4
+ 0: aaaabbbbzz
+ 1: bbbb
+ 2: z
+ 3: z
+    aaaabbbbzzzz\O5
+ 0: aaaabbbbzz
+ 1: bbbb
+ 2: z
+ 3: z
+    
+/^.?abcd/S 
+Capturing subpattern count = 0
+Options: anchored
+No first char
+Need char = 'd'
+Study returned NULL
+
+/\(             # ( at start
+  (?:           # Non-capturing bracket
+  (?>[^()]+)    # Either a sequence of non-brackets (no backtracking)
+  |             # Or
+  (?R)          # Recurse - i.e. nested bracketed string
+  )*            # Zero or more contents
+  \)            # Closing )
+  /x
+Capturing subpattern count = 0
+Options: extended
+First char = '('
+Need char = ')'
+    (abcd)
+ 0: (abcd)
+    (abcd)xyz
+ 0: (abcd)
+    xyz(abcd)
+ 0: (abcd)
+    (ab(xy)cd)pqr 
+ 0: (ab(xy)cd)
+    (ab(xycd)pqr 
+ 0: (xycd)
+    () abc () 
+ 0: ()
+    12(abcde(fsh)xyz(foo(bar))lmno)89
+ 0: (abcde(fsh)xyz(foo(bar))lmno)
+    *** Failers
+No match
+    abcd 
+No match
+    abcd)
+No match
+    (abcd  
+No match
+
+/\(  ( (?>[^()]+) | (?R) )* \) /xg
+Capturing subpattern count = 1
+Options: extended
+First char = '('
+Need char = ')'
+    (ab(xy)cd)pqr 
+ 0: (ab(xy)cd)
+ 1: cd
+    1(abcd)(x(y)z)pqr
+ 0: (abcd)
+ 1: abcd
+ 0: (x(y)z)
+ 1: z
+
+/\(  (?: (?>[^()]+) | (?R) ) \) /x
+Capturing subpattern count = 0
+Options: extended
+First char = '('
+Need char = ')'
+    (abcd)
+ 0: (abcd)
+    (ab(xy)cd)
+ 0: (xy)
+    (a(b(c)d)e) 
+ 0: (c)
+    ((ab)) 
+ 0: ((ab))
+    *** Failers
+No match
+    ()   
+No match
+
+/\(  (?: (?>[^()]+) | (?R) )? \) /x
+Capturing subpattern count = 0
+Options: extended
+First char = '('
+Need char = ')'
+    ()
+ 0: ()
+    12(abcde(fsh)xyz(foo(bar))lmno)89
+ 0: (fsh)
+
+/\(  ( (?>[^()]+) | (?R) )* \) /x
+Capturing subpattern count = 1
+Options: extended
+First char = '('
+Need char = ')'
+    (ab(xy)cd)
+ 0: (ab(xy)cd)
+ 1: cd
+
+/\( ( ( (?>[^()]+) | (?R) )* ) \) /x
+Capturing subpattern count = 2
+Options: extended
+First char = '('
+Need char = ')'
+    (ab(xy)cd)
+ 0: (ab(xy)cd)
+ 1: ab(xy)cd
+ 2: cd
+
+/\( (123)? ( ( (?>[^()]+) | (?R) )* ) \) /x
+Capturing subpattern count = 3
+Options: extended
+First char = '('
+Need char = ')'
+    (ab(xy)cd)
+ 0: (ab(xy)cd)
+ 1: <unset>
+ 2: ab(xy)cd
+ 3: cd
+    (123ab(xy)cd)
+ 0: (123ab(xy)cd)
+ 1: 123
+ 2: ab(xy)cd
+ 3: cd
+
+/\( ( (123)? ( (?>[^()]+) | (?R) )* ) \) /x
+Capturing subpattern count = 3
+Options: extended
+First char = '('
+Need char = ')'
+    (ab(xy)cd)
+ 0: (ab(xy)cd)
+ 1: ab(xy)cd
+ 2: <unset>
+ 3: cd
+    (123ab(xy)cd)
+ 0: (123ab(xy)cd)
+ 1: 123ab(xy)cd
+ 2: 123
+ 3: cd
+
+/\( (((((((((( ( (?>[^()]+) | (?R) )* )))))))))) \) /x
+Capturing subpattern count = 11
+Options: extended
+First char = '('
+Need char = ')'
+    (ab(xy)cd)
+ 0: (ab(xy)cd)
+ 1: ab(xy)cd
+ 2: ab(xy)cd
+ 3: ab(xy)cd
+ 4: ab(xy)cd
+ 5: ab(xy)cd
+ 6: ab(xy)cd
+ 7: ab(xy)cd
+ 8: ab(xy)cd
+ 9: ab(xy)cd
+10: ab(xy)cd
+11: cd
+
+/\( ( ( (?>[^()<>]+) | ((?>[^()]+)) | (?R) )* ) \) /x
+Capturing subpattern count = 3
+Options: extended
+First char = '('
+Need char = ')'
+    (abcd(xyz<p>qrs)123)
+ 0: (abcd(xyz<p>qrs)123)
+ 1: abcd(xyz<p>qrs)123
+ 2: 123
+ 3: <p>qrs
+
+/\( ( ( (?>[^()]+) | ((?R)) )* ) \) /x
+Capturing subpattern count = 3
+Options: extended
+First char = '('
+Need char = ')'
+    (ab(cd)ef)
+ 0: (ab(cd)ef)
+ 1: ab(cd)ef
+ 2: ef
+ 3: (cd)
+    (ab(cd(ef)gh)ij)
+ 0: (ab(cd(ef)gh)ij)
+ 1: ab(cd(ef)gh)ij
+ 2: ij
+ 3: (cd(ef)gh)
+
+/^[[:alnum:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [0-9A-Za-z]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+
+/^[[:alpha:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [A-Za-z]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+             
+/^[[:ascii:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [\x00-\x7f]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+
+/^[[:cntrl:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [\x00-\x1f\x7f]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+
+/^[[:digit:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [0-9]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+
+/^[[:graph:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [!-~]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+
+/^[[:lower:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [a-z]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+
+/^[[:print:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [ -~]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+
+/^[[:punct:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [!-/:-@[-`{-~]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+
+/^[[:space:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [\x09-\x0d ]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+
+/^[[:upper:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [A-Z]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+
+/^[[:xdigit:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [0-9A-Fa-f]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+
+/^[[:word:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [0-9A-Z_a-z]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+
+/^[[:^cntrl:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [ -~\x80-\xff]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+
+/^[12[:^digit:]]/D
+------------------------------------------------------------------
+  0  37 Bra 0
+  3     ^
+  4     [\x00-/1-2:-\xff]
+ 37  37 Ket
+ 40     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+Options: anchored
+No first char
+No need char
+
+/[01[:alpha:]%]/D
+------------------------------------------------------------------
+  0  36 Bra 0
+  3     [%0-1A-Za-z]
+ 36  36 Ket
+ 39     End
+------------------------------------------------------------------
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+
+/[[.ch.]]/
+Failed: POSIX collating elements are not supported at offset 1
+
+/[[=ch=]]/
+Failed: POSIX collating elements are not supported at offset 1
+
+/[[:rhubarb:]]/
+Failed: unknown POSIX class name at offset 3
+
+/[[:upper:]]/i
+Capturing subpattern count = 0
+Options: caseless
+No first char
+No need char
+    A
+ 0: A
+    a 
+ 0: a
+    
+/[[:lower:]]/i
+Capturing subpattern count = 0
+Options: caseless
+No first char
+No need char
+    A
+ 0: A
+    a 
+ 0: a
+
+/((?-i)[[:lower:]])[[:lower:]]/i
+Capturing subpattern count = 1
+Options: caseless
+Case state changes
+No first char
+No need char
+    ab
+ 0: ab
+ 1: a
+    aB
+ 0: aB
+ 1: a
+    *** Failers
+ 0: ai
+ 1: a
+    Ab
+No match
+    AB        
+No match
+
+/ End of test input /
+Capturing subpattern count = 0
+No options
+First char = ' '
+Need char = ' '
+
diff --git a/ext/pcre/pcrelib/testdata/testoutput3 b/ext/pcre/pcrelib/testdata/testoutput3
new file mode 100644 (file)
index 0000000..8eb215e
--- /dev/null
@@ -0,0 +1,2929 @@
+PCRE version 3.1 09-Feb-2000
+
+/(?<!bar)foo/
+    foo
+ 0: foo
+    catfood
+ 0: foo
+    arfootle
+ 0: foo
+    rfoosh
+ 0: foo
+    *** Failers
+No match
+    barfoo
+No match
+    towbarfoo
+No match
+
+/\w{3}(?<!bar)foo/
+    catfood
+ 0: catfoo
+    *** Failers
+No match
+    foo
+No match
+    barfoo
+No match
+    towbarfoo
+No match
+
+/(?<=(foo)a)bar/
+    fooabar
+ 0: bar
+ 1: foo
+    *** Failers
+No match
+    bar
+No match
+    foobbar
+No match
+      
+/\Aabc\z/m
+    abc
+ 0: abc
+    *** Failers
+No match
+    abc\n   
+No match
+    qqq\nabc
+No match
+    abc\nzzz
+No match
+    qqq\nabc\nzzz
+No match
+
+"(?>.*/)foo"
+    /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/it/you/see/
+No match
+
+"(?>.*/)foo"
+    /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo
+ 0: /this/is/a/very/long/line/in/deed/with/very/many/slashes/in/and/foo
+
+/(?>(\.\d\d[1-9]?))\d+/
+    1.230003938
+ 0: .230003938
+ 1: .23
+    1.875000282
+ 0: .875000282
+ 1: .875
+    *** Failers 
+No match
+    1.235 
+No match
+
+/^((?>\w+)|(?>\s+))*$/
+    now is the time for all good men to come to the aid of the party
+ 0: now is the time for all good men to come to the aid of the party
+ 1: party
+    *** Failers
+No match
+    this is not a line with only words and spaces!
+No match
+    
+/(\d+)(\w)/
+    12345a
+ 0: 12345a
+ 1: 12345
+ 2: a
+    12345+ 
+ 0: 12345
+ 1: 1234
+ 2: 5
+
+/((?>\d+))(\w)/
+    12345a
+ 0: 12345a
+ 1: 12345
+ 2: a
+    *** Failers
+No match
+    12345+ 
+No match
+
+/(?>a+)b/
+    aaab
+ 0: aaab
+
+/((?>a+)b)/
+    aaab
+ 0: aaab
+ 1: aaab
+
+/(?>(a+))b/
+    aaab
+ 0: aaab
+ 1: aaa
+
+/(?>b)+/
+    aaabbbccc
+ 0: bbb
+
+/(?>a+|b+|c+)*c/
+    aaabbbbccccd
+ 0: aaabbbbc
+
+/((?>[^()]+)|\([^()]*\))+/
+    ((abc(ade)ufh()()x
+ 0: abc(ade)ufh()()x
+ 1: x
+    
+/\(((?>[^()]+)|\([^()]+\))+\)/ 
+    (abc)
+ 0: (abc)
+ 1: abc
+    (abc(def)xyz)
+ 0: (abc(def)xyz)
+ 1: xyz
+    *** Failers
+No match
+    ((()aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa   
+No match
+
+/a(?-i)b/i
+    ab
+ 0: ab
+    *** Failers 
+No match
+    Ab
+No match
+    aB
+No match
+    AB
+No match
+        
+/(a (?x)b c)d e/
+    a bcd e
+ 0: a bcd e
+ 1: a bc
+    *** Failers
+No match
+    a b cd e
+No match
+    abcd e   
+No match
+    a bcde 
+No match
+/(a b(?x)c d (?-x)e f)/
+    a bcde f
+ 0: a bcde f
+ 1: a bcde f
+    *** Failers
+No match
+    abcdef  
+No match
+
+/(a(?i)b)c/
+    abc
+ 0: abc
+ 1: ab
+    aBc
+ 0: aBc
+ 1: aB
+    *** Failers
+No match
+    abC
+No match
+    aBC  
+No match
+    Abc
+No match
+    ABc
+No match
+    ABC
+No match
+    AbC
+No match
+    
+/a(?i:b)c/
+    abc
+ 0: abc
+    aBc
+ 0: aBc
+    *** Failers 
+No match
+    ABC
+No match
+    abC
+No match
+    aBC
+No match
+    
+/a(?i:b)*c/
+    aBc
+ 0: aBc
+    aBBc
+ 0: aBBc
+    *** Failers 
+No match
+    aBC
+No match
+    aBBC
+No match
+    
+/a(?=b(?i)c)\w\wd/
+    abcd
+ 0: abcd
+    abCd
+ 0: abCd
+    *** Failers
+No match
+    aBCd
+No match
+    abcD     
+No match
+    
+/(?s-i:more.*than).*million/i
+    more than million
+ 0: more than million
+    more than MILLION
+ 0: more than MILLION
+    more \n than Million 
+ 0: more \x0a than Million
+    *** Failers
+No match
+    MORE THAN MILLION    
+No match
+    more \n than \n million 
+No match
+
+/(?:(?s-i)more.*than).*million/i
+    more than million
+ 0: more than million
+    more than MILLION
+ 0: more than MILLION
+    more \n than Million 
+ 0: more \x0a than Million
+    *** Failers
+No match
+    MORE THAN MILLION    
+No match
+    more \n than \n million 
+No match
+    
+/(?>a(?i)b+)+c/ 
+    abc
+ 0: abc
+    aBbc
+ 0: aBbc
+    aBBc 
+ 0: aBBc
+    *** Failers
+No match
+    Abc
+No match
+    abAb    
+No match
+    abbC 
+No match
+    
+/(?=a(?i)b)\w\wc/
+    abc
+ 0: abc
+    aBc
+ 0: aBc
+    *** Failers
+No match
+    Ab 
+No match
+    abC
+No match
+    aBC     
+No match
+    
+/(?<=a(?i)b)(\w\w)c/
+    abxxc
+ 0: xxc
+ 1: xx
+    aBxxc
+ 0: xxc
+ 1: xx
+    *** Failers
+No match
+    Abxxc
+No match
+    ABxxc
+No match
+    abxxC      
+No match
+
+/(?:(a)|b)(?(1)A|B)/
+    aA
+ 0: aA
+ 1: a
+    bB
+ 0: bB
+    *** Failers
+No match
+    aB
+No match
+    bA    
+No match
+
+/^(a)?(?(1)a|b)+$/
+    aa
+ 0: aa
+ 1: a
+    b
+ 0: b
+    bb  
+ 0: bb
+    *** Failers
+No match
+    ab   
+No match
+
+/^(?(?=abc)\w{3}:|\d\d)$/
+    abc:
+ 0: abc:
+    12
+ 0: 12
+    *** Failers
+No match
+    123
+No match
+    xyz    
+No match
+
+/^(?(?!abc)\d\d|\w{3}:)$/
+    abc:
+ 0: abc:
+    12
+ 0: 12
+    *** Failers
+No match
+    123
+No match
+    xyz    
+No match
+    
+/(?(?<=foo)bar|cat)/
+    foobar
+ 0: bar
+    cat
+ 0: cat
+    fcat
+ 0: cat
+    focat   
+ 0: cat
+    *** Failers
+No match
+    foocat  
+No match
+
+/(?(?<!foo)cat|bar)/
+    foobar
+ 0: bar
+    cat
+ 0: cat
+    fcat
+ 0: cat
+    focat   
+ 0: cat
+    *** Failers
+No match
+    foocat  
+No match
+
+/( \( )? [^()]+ (?(1) \) |) /x
+    abcd
+ 0: abcd
+    (abcd)
+ 0: (abcd)
+ 1: (
+    the quick (abcd) fox
+ 0: the quick 
+    (abcd   
+ 0: abcd
+
+/( \( )? [^()]+ (?(1) \) ) /x
+    abcd
+ 0: abcd
+    (abcd)
+ 0: (abcd)
+ 1: (
+    the quick (abcd) fox
+ 0: the quick 
+    (abcd   
+ 0: abcd
+
+/^(?(2)a|(1)(2))+$/
+    12
+ 0: 12
+ 1: 1
+ 2: 2
+    12a
+ 0: 12a
+ 1: 1
+ 2: 2
+    12aa
+ 0: 12aa
+ 1: 1
+ 2: 2
+    *** Failers
+No match
+    1234    
+No match
+
+/((?i)blah)\s+\1/
+    blah blah
+ 0: blah blah
+ 1: blah
+    BLAH BLAH
+ 0: BLAH BLAH
+ 1: BLAH
+    Blah Blah
+ 0: Blah Blah
+ 1: Blah
+    blaH blaH
+ 0: blaH blaH
+ 1: blaH
+    *** Failers
+No match
+    blah BLAH
+No match
+    Blah blah      
+No match
+    blaH blah 
+No match
+
+/((?i)blah)\s+(?i:\1)/
+    blah blah
+ 0: blah blah
+ 1: blah
+    BLAH BLAH
+ 0: BLAH BLAH
+ 1: BLAH
+    Blah Blah
+ 0: Blah Blah
+ 1: Blah
+    blaH blaH
+ 0: blaH blaH
+ 1: blaH
+    blah BLAH
+ 0: blah BLAH
+ 1: blah
+    Blah blah      
+ 0: Blah blah
+ 1: Blah
+    blaH blah 
+ 0: blaH blah
+ 1: blaH
+
+/(?>a*)*/
+    a
+ 0: a
+    aa
+ 0: aa
+    aaaa
+ 0: aaaa
+    
+/(abc|)+/
+    abc
+ 0: abc
+ 1: 
+    abcabc
+ 0: abcabc
+ 1: 
+    abcabcabc
+ 0: abcabcabc
+ 1: 
+    xyz      
+ 0: 
+ 1: 
+
+/([a]*)*/
+    a
+ 0: a
+ 1: 
+    aaaaa 
+ 0: aaaaa
+ 1: 
+/([ab]*)*/
+    a
+ 0: a
+ 1: 
+    b
+ 0: b
+ 1: 
+    ababab
+ 0: ababab
+ 1: 
+    aaaabcde
+ 0: aaaab
+ 1: 
+    bbbb    
+ 0: bbbb
+ 1: 
+/([^a]*)*/
+    b
+ 0: b
+ 1: 
+    bbbb
+ 0: bbbb
+ 1: 
+    aaa   
+ 0: 
+ 1: 
+/([^ab]*)*/
+    cccc
+ 0: cccc
+ 1: 
+    abab  
+ 0: 
+ 1: 
+/([a]*?)*/
+    a
+ 0: 
+ 1: 
+    aaaa 
+ 0: 
+ 1: 
+/([ab]*?)*/
+    a
+ 0: 
+ 1: 
+    b
+ 0: 
+ 1: 
+    abab
+ 0: 
+ 1: 
+    baba   
+ 0: 
+ 1: 
+/([^a]*?)*/
+    b
+ 0: 
+ 1: 
+    bbbb
+ 0: 
+ 1: 
+    aaa   
+ 0: 
+ 1: 
+/([^ab]*?)*/
+    c
+ 0: 
+ 1: 
+    cccc
+ 0: 
+ 1: 
+    baba   
+ 0: 
+ 1: 
+/(?>a*)*/
+    a
+ 0: a
+    aaabcde 
+ 0: aaa
+/((?>a*))*/
+    aaaaa
+ 0: aaaaa
+ 1: 
+    aabbaa 
+ 0: aa
+ 1: 
+/((?>a*?))*/
+    aaaaa
+ 0: 
+ 1: 
+    aabbaa 
+ 0: 
+ 1: 
+
+/(?(?=[^a-z]+[a-z])  \d{2}-[a-z]{3}-\d{2}  |  \d{2}-\d{2}-\d{2} ) /x
+    12-sep-98
+ 0: 12-sep-98
+    12-09-98
+ 0: 12-09-98
+    *** Failers
+No match
+    sep-12-98
+No match
+        
+/(?<=(foo))bar\1/
+    foobarfoo
+ 0: barfoo
+ 1: foo
+    foobarfootling 
+ 0: barfoo
+ 1: foo
+    *** Failers
+No match
+    foobar
+No match
+    barfoo   
+No match
+
+/(?i:saturday|sunday)/
+    saturday
+ 0: saturday
+    sunday
+ 0: sunday
+    Saturday
+ 0: Saturday
+    Sunday
+ 0: Sunday
+    SATURDAY
+ 0: SATURDAY
+    SUNDAY
+ 0: SUNDAY
+    SunDay
+ 0: SunDay
+    
+/(a(?i)bc|BB)x/
+    abcx
+ 0: abcx
+ 1: abc
+    aBCx
+ 0: aBCx
+ 1: aBC
+    bbx
+ 0: bbx
+ 1: bb
+    BBx
+ 0: BBx
+ 1: BB
+    *** Failers
+No match
+    abcX
+No match
+    aBCX
+No match
+    bbX
+No match
+    BBX               
+No match
+
+/^([ab](?i)[cd]|[ef])/
+    ac
+ 0: ac
+ 1: ac
+    aC
+ 0: aC
+ 1: aC
+    bD
+ 0: bD
+ 1: bD
+    elephant
+ 0: e
+ 1: e
+    Europe 
+ 0: E
+ 1: E
+    frog
+ 0: f
+ 1: f
+    France
+ 0: F
+ 1: F
+    *** Failers
+No match
+    Africa     
+No match
+
+/^(ab|a(?i)[b-c](?m-i)d|x(?i)y|z)/
+    ab
+ 0: ab
+ 1: ab
+    aBd
+ 0: aBd
+ 1: aBd
+    xy
+ 0: xy
+ 1: xy
+    xY
+ 0: xY
+ 1: xY
+    zebra
+ 0: z
+ 1: z
+    Zambesi
+ 0: Z
+ 1: Z
+    *** Failers
+No match
+    aCD  
+No match
+    XY  
+No match
+
+/(?<=foo\n)^bar/m
+    foo\nbar
+ 0: bar
+    *** Failers
+No match
+    bar
+No match
+    baz\nbar   
+No match
+
+/(?<=(?<!foo)bar)baz/
+    barbaz
+ 0: baz
+    barbarbaz 
+ 0: baz
+    koobarbaz 
+ 0: baz
+    *** Failers
+No match
+    baz
+No match
+    foobarbaz 
+No match
+
+/The case of aaaaaa is missed out below because I think Perl 5.005_02 gets/
+/it wrong; it sets $1 to aaa rather than aa. Compare the following test,/
+No match
+/where it does set $1 to aa when matching aaaaaa./
+No match
+
+/^(a\1?){4}$/
+    a
+No match
+    aa
+No match
+    aaa
+No match
+    aaaa
+ 0: aaaa
+ 1: a
+    aaaaa
+ 0: aaaaa
+ 1: a
+    aaaaaaa
+ 0: aaaaaaa
+ 1: a
+    aaaaaaaa
+No match
+    aaaaaaaaa
+No match
+    aaaaaaaaaa
+ 0: aaaaaaaaaa
+ 1: aaaa
+    aaaaaaaaaaa
+No match
+    aaaaaaaaaaaa
+No match
+    aaaaaaaaaaaaa
+No match
+    aaaaaaaaaaaaaa
+No match
+    aaaaaaaaaaaaaaa
+No match
+    aaaaaaaaaaaaaaaa               
+No match
+
+/^(a\1?)(a\1?)(a\2?)(a\3?)$/
+    a
+No match
+    aa
+No match
+    aaa
+No match
+    aaaa
+ 0: aaaa
+ 1: a
+ 2: a
+ 3: a
+ 4: a
+    aaaaa
+ 0: aaaaa
+ 1: a
+ 2: aa
+ 3: a
+ 4: a
+    aaaaaa
+ 0: aaaaaa
+ 1: a
+ 2: aa
+ 3: a
+ 4: aa
+    aaaaaaa
+ 0: aaaaaaa
+ 1: a
+ 2: aa
+ 3: aaa
+ 4: a
+    aaaaaaaa
+No match
+    aaaaaaaaa
+No match
+    aaaaaaaaaa
+ 0: aaaaaaaaaa
+ 1: a
+ 2: aa
+ 3: aaa
+ 4: aaaa
+    aaaaaaaaaaa
+No match
+    aaaaaaaaaaaa
+No match
+    aaaaaaaaaaaaa
+No match
+    aaaaaaaaaaaaaa
+No match
+    aaaaaaaaaaaaaaa
+No match
+    aaaaaaaaaaaaaaaa               
+No match
+
+/The following tests are taken from the Perl 5.005 test suite; some of them/
+/are compatible with 5.004, but I'd rather not have to sort them out./
+No match
+
+/abc/
+    abc
+ 0: abc
+    xabcy
+ 0: abc
+    ababc
+ 0: abc
+    *** Failers
+No match
+    xbc
+No match
+    axc
+No match
+    abx
+No match
+
+/ab*c/
+    abc
+ 0: abc
+
+/ab*bc/
+    abc
+ 0: abc
+    abbc
+ 0: abbc
+    abbbbc
+ 0: abbbbc
+
+/.{1}/
+    abbbbc
+ 0: a
+
+/.{3,4}/
+    abbbbc
+ 0: abbb
+
+/ab{0,}bc/
+    abbbbc
+ 0: abbbbc
+
+/ab+bc/
+    abbc
+ 0: abbc
+    *** Failers
+No match
+    abc
+No match
+    abq
+No match
+
+/ab{1,}bc/
+
+/ab+bc/
+    abbbbc
+ 0: abbbbc
+
+/ab{1,}bc/
+    abbbbc
+ 0: abbbbc
+
+/ab{1,3}bc/
+    abbbbc
+ 0: abbbbc
+
+/ab{3,4}bc/
+    abbbbc
+ 0: abbbbc
+
+/ab{4,5}bc/
+    *** Failers
+No match
+    abq
+No match
+    abbbbc
+No match
+
+/ab?bc/
+    abbc
+ 0: abbc
+    abc
+ 0: abc
+
+/ab{0,1}bc/
+    abc
+ 0: abc
+
+/ab?bc/
+
+/ab?c/
+    abc
+ 0: abc
+
+/ab{0,1}c/
+    abc
+ 0: abc
+
+/^abc$/
+    abc
+ 0: abc
+    *** Failers
+No match
+    abbbbc
+No match
+    abcc
+No match
+
+/^abc/
+    abcc
+ 0: abc
+
+/^abc$/
+
+/abc$/
+    aabc
+ 0: abc
+    *** Failers
+No match
+    aabc
+ 0: abc
+    aabcd
+No match
+
+/^/
+    abc
+ 0: 
+
+/$/
+    abc
+ 0: 
+
+/a.c/
+    abc
+ 0: abc
+    axc
+ 0: axc
+
+/a.*c/
+    axyzc
+ 0: axyzc
+
+/a[bc]d/
+    abd
+ 0: abd
+    *** Failers
+No match
+    axyzd
+No match
+    abc
+No match
+
+/a[b-d]e/
+    ace
+ 0: ace
+
+/a[b-d]/
+    aac
+ 0: ac
+
+/a[-b]/
+    a-
+ 0: a-
+
+/a[b-]/
+    a-
+ 0: a-
+
+/a]/
+    a]
+ 0: a]
+
+/a[]]b/
+    a]b
+ 0: a]b
+
+/a[^bc]d/
+    aed
+ 0: aed
+    *** Failers
+No match
+    abd
+No match
+    abd
+No match
+
+/a[^-b]c/
+    adc
+ 0: adc
+
+/a[^]b]c/
+    adc
+ 0: adc
+    *** Failers
+No match
+    a-c
+ 0: a-c
+    a]c
+No match
+
+/\ba\b/
+    a-
+ 0: a
+    -a
+ 0: a
+    -a-
+ 0: a
+
+/\by\b/
+    *** Failers
+No match
+    xy
+No match
+    yz
+No match
+    xyz
+No match
+
+/\Ba\B/
+    *** Failers
+ 0: a
+    a-
+No match
+    -a
+No match
+    -a-
+No match
+
+/\By\b/
+    xy
+ 0: y
+
+/\by\B/
+    yz
+ 0: y
+
+/\By\B/
+    xyz
+ 0: y
+
+/\w/
+    a
+ 0: a
+
+/\W/
+    -
+ 0: -
+    *** Failers
+ 0: *
+    -
+ 0: -
+    a
+No match
+
+/a\sb/
+    a b
+ 0: a b
+
+/a\Sb/
+    a-b
+ 0: a-b
+    *** Failers
+No match
+    a-b
+ 0: a-b
+    a b
+No match
+
+/\d/
+    1
+ 0: 1
+
+/\D/
+    -
+ 0: -
+    *** Failers
+ 0: *
+    -
+ 0: -
+    1
+No match
+
+/[\w]/
+    a
+ 0: a
+
+/[\W]/
+    -
+ 0: -
+    *** Failers
+ 0: *
+    -
+ 0: -
+    a
+No match
+
+/a[\s]b/
+    a b
+ 0: a b
+
+/a[\S]b/
+    a-b
+ 0: a-b
+    *** Failers
+No match
+    a-b
+ 0: a-b
+    a b
+No match
+
+/[\d]/
+    1
+ 0: 1
+
+/[\D]/
+    -
+ 0: -
+    *** Failers
+ 0: *
+    -
+ 0: -
+    1
+No match
+
+/ab|cd/
+    abc
+ 0: ab
+    abcd
+ 0: ab
+
+/()ef/
+    def
+ 0: ef
+ 1: 
+
+/$b/
+
+/a\(b/
+    a(b
+ 0: a(b
+
+/a\(*b/
+    ab
+ 0: ab
+    a((b
+ 0: a((b
+
+/a\\b/
+    a\b
+No match
+
+/((a))/
+    abc
+ 0: a
+ 1: a
+ 2: a
+
+/(a)b(c)/
+    abc
+ 0: abc
+ 1: a
+ 2: c
+
+/a+b+c/
+    aabbabc
+ 0: abc
+
+/a{1,}b{1,}c/
+    aabbabc
+ 0: abc
+
+/a.+?c/
+    abcabc
+ 0: abc
+
+/(a+|b)*/
+    ab
+ 0: ab
+ 1: b
+
+/(a+|b){0,}/
+    ab
+ 0: ab
+ 1: b
+
+/(a+|b)+/
+    ab
+ 0: ab
+ 1: b
+
+/(a+|b){1,}/
+    ab
+ 0: ab
+ 1: b
+
+/(a+|b)?/
+    ab
+ 0: a
+ 1: a
+
+/(a+|b){0,1}/
+    ab
+ 0: a
+ 1: a
+
+/[^ab]*/
+    cde
+ 0: cde
+
+/abc/
+    *** Failers
+No match
+    b
+No match
+    
+
+/a*/
+    
+
+/([abc])*d/
+    abbbcd
+ 0: abbbcd
+ 1: c
+
+/([abc])*bcd/
+    abcd
+ 0: abcd
+ 1: a
+
+/a|b|c|d|e/
+    e
+ 0: e
+
+/(a|b|c|d|e)f/
+    ef
+ 0: ef
+ 1: e
+
+/abcd*efg/
+    abcdefg
+ 0: abcdefg
+
+/ab*/
+    xabyabbbz
+ 0: ab
+    xayabbbz
+ 0: a
+
+/(ab|cd)e/
+    abcde
+ 0: cde
+ 1: cd
+
+/[abhgefdc]ij/
+    hij
+ 0: hij
+
+/^(ab|cd)e/
+
+/(abc|)ef/
+    abcdef
+ 0: ef
+ 1: 
+
+/(a|b)c*d/
+    abcd
+ 0: bcd
+ 1: b
+
+/(ab|ab*)bc/
+    abc
+ 0: abc
+ 1: a
+
+/a([bc]*)c*/
+    abc
+ 0: abc
+ 1: bc
+
+/a([bc]*)(c*d)/
+    abcd
+ 0: abcd
+ 1: bc
+ 2: d
+
+/a([bc]+)(c*d)/
+    abcd
+ 0: abcd
+ 1: bc
+ 2: d
+
+/a([bc]*)(c+d)/
+    abcd
+ 0: abcd
+ 1: b
+ 2: cd
+
+/a[bcd]*dcdcde/
+    adcdcde
+ 0: adcdcde
+
+/a[bcd]+dcdcde/
+    *** Failers
+No match
+    abcde
+No match
+    adcdcde
+No match
+
+/(ab|a)b*c/
+    abc
+ 0: abc
+ 1: ab
+
+/((a)(b)c)(d)/
+    abcd
+ 0: abcd
+ 1: abc
+ 2: a
+ 3: b
+ 4: d
+
+/[a-zA-Z_][a-zA-Z0-9_]*/
+    alpha
+ 0: alpha
+
+/^a(bc+|b[eh])g|.h$/
+    abh
+ 0: bh
+
+/(bc+d$|ef*g.|h?i(j|k))/
+    effgz
+ 0: effgz
+ 1: effgz
+    ij
+ 0: ij
+ 1: ij
+ 2: j
+    reffgz
+ 0: effgz
+ 1: effgz
+    *** Failers
+No match
+    effg
+No match
+    bcdd
+No match
+
+/((((((((((a))))))))))/
+    a
+ 0: a
+ 1: a
+ 2: a
+ 3: a
+ 4: a
+ 5: a
+ 6: a
+ 7: a
+ 8: a
+ 9: a
+10: a
+
+/((((((((((a))))))))))\10/
+    aa
+ 0: aa
+ 1: a
+ 2: a
+ 3: a
+ 4: a
+ 5: a
+ 6: a
+ 7: a
+ 8: a
+ 9: a
+10: a
+
+/(((((((((a)))))))))/
+    a
+ 0: a
+ 1: a
+ 2: a
+ 3: a
+ 4: a
+ 5: a
+ 6: a
+ 7: a
+ 8: a
+ 9: a
+
+/multiple words of text/
+    *** Failers
+No match
+    aa
+No match
+    uh-uh
+No match
+
+/multiple words/
+    multiple words, yeah
+ 0: multiple words
+
+/(.*)c(.*)/
+    abcde
+ 0: abcde
+ 1: ab
+ 2: de
+
+/\((.*), (.*)\)/
+    (a, b)
+ 0: (a, b)
+ 1: a
+ 2: b
+
+/[k]/
+
+/abcd/
+    abcd
+ 0: abcd
+
+/a(bc)d/
+    abcd
+ 0: abcd
+ 1: bc
+
+/a[-]?c/
+    ac
+ 0: ac
+
+/(abc)\1/
+    abcabc
+ 0: abcabc
+ 1: abc
+
+/([a-c]*)\1/
+    abcabc
+ 0: abcabc
+ 1: abc
+
+/(a)|\1/
+    a
+ 0: a
+ 1: a
+    *** Failers
+ 0: a
+ 1: a
+    ab
+ 0: a
+ 1: a
+    x
+No match
+
+/(([a-c])b*?\2)*/
+    ababbbcbc
+ 0: ababb
+ 1: bb
+ 2: b
+
+/(([a-c])b*?\2){3}/
+    ababbbcbc
+ 0: ababbbcbc
+ 1: cbc
+ 2: c
+
+/((\3|b)\2(a)x)+/
+    aaaxabaxbaaxbbax
+ 0: bbax
+ 1: bbax
+ 2: b
+ 3: a
+
+/((\3|b)\2(a)){2,}/
+    bbaababbabaaaaabbaaaabba
+ 0: bbaaaabba
+ 1: bba
+ 2: b
+ 3: a
+
+/abc/i
+    ABC
+ 0: ABC
+    XABCY
+ 0: ABC
+    ABABC
+ 0: ABC
+    *** Failers
+No match
+    aaxabxbaxbbx
+No match
+    XBC
+No match
+    AXC
+No match
+    ABX
+No match
+
+/ab*c/i
+    ABC
+ 0: ABC
+
+/ab*bc/i
+    ABC
+ 0: ABC
+    ABBC
+ 0: ABBC
+
+/ab*?bc/i
+    ABBBBC
+ 0: ABBBBC
+
+/ab{0,}?bc/i
+    ABBBBC
+ 0: ABBBBC
+
+/ab+?bc/i
+    ABBC
+ 0: ABBC
+
+/ab+bc/i
+    *** Failers
+No match
+    ABC
+No match
+    ABQ
+No match
+
+/ab{1,}bc/i
+
+/ab+bc/i
+    ABBBBC
+ 0: ABBBBC
+
+/ab{1,}?bc/i
+    ABBBBC
+ 0: ABBBBC
+
+/ab{1,3}?bc/i
+    ABBBBC
+ 0: ABBBBC
+
+/ab{3,4}?bc/i
+    ABBBBC
+ 0: ABBBBC
+
+/ab{4,5}?bc/i
+    *** Failers
+No match
+    ABQ
+No match
+    ABBBBC
+No match
+
+/ab??bc/i
+    ABBC
+ 0: ABBC
+    ABC
+ 0: ABC
+
+/ab{0,1}?bc/i
+    ABC
+ 0: ABC
+
+/ab??bc/i
+
+/ab??c/i
+    ABC
+ 0: ABC
+
+/ab{0,1}?c/i
+    ABC
+ 0: ABC
+
+/^abc$/i
+    ABC
+ 0: ABC
+    *** Failers
+No match
+    ABBBBC
+No match
+    ABCC
+No match
+
+/^abc/i
+    ABCC
+ 0: ABC
+
+/^abc$/i
+
+/abc$/i
+    AABC
+ 0: ABC
+
+/^/i
+    ABC
+ 0: 
+
+/$/i
+    ABC
+ 0: 
+
+/a.c/i
+    ABC
+ 0: ABC
+    AXC
+ 0: AXC
+
+/a.*?c/i
+    AXYZC
+ 0: AXYZC
+
+/a.*c/i
+    *** Failers
+No match
+    AABC
+ 0: AABC
+    AXYZD
+No match
+
+/a[bc]d/i
+    ABD
+ 0: ABD
+
+/a[b-d]e/i
+    ACE
+ 0: ACE
+    *** Failers
+No match
+    ABC
+No match
+    ABD
+No match
+
+/a[b-d]/i
+    AAC
+ 0: AC
+
+/a[-b]/i
+    A-
+ 0: A-
+
+/a[b-]/i
+    A-
+ 0: A-
+
+/a]/i
+    A]
+ 0: A]
+
+/a[]]b/i
+    A]B
+ 0: A]B
+
+/a[^bc]d/i
+    AED
+ 0: AED
+
+/a[^-b]c/i
+    ADC
+ 0: ADC
+    *** Failers
+No match
+    ABD
+No match
+    A-C
+No match
+
+/a[^]b]c/i
+    ADC
+ 0: ADC
+
+/ab|cd/i
+    ABC
+ 0: AB
+    ABCD
+ 0: AB
+
+/()ef/i
+    DEF
+ 0: EF
+ 1: 
+
+/$b/i
+    *** Failers
+No match
+    A]C
+No match
+    B
+No match
+
+/a\(b/i
+    A(B
+ 0: A(B
+
+/a\(*b/i
+    AB
+ 0: AB
+    A((B
+ 0: A((B
+
+/a\\b/i
+    A\B
+No match
+
+/((a))/i
+    ABC
+ 0: A
+ 1: A
+ 2: A
+
+/(a)b(c)/i
+    ABC
+ 0: ABC
+ 1: A
+ 2: C
+
+/a+b+c/i
+    AABBABC
+ 0: ABC
+
+/a{1,}b{1,}c/i
+    AABBABC
+ 0: ABC
+
+/a.+?c/i
+    ABCABC
+ 0: ABC
+
+/a.*?c/i
+    ABCABC
+ 0: ABC
+
+/a.{0,5}?c/i
+    ABCABC
+ 0: ABC
+
+/(a+|b)*/i
+    AB
+ 0: AB
+ 1: B
+
+/(a+|b){0,}/i
+    AB
+ 0: AB
+ 1: B
+
+/(a+|b)+/i
+    AB
+ 0: AB
+ 1: B
+
+/(a+|b){1,}/i
+    AB
+ 0: AB
+ 1: B
+
+/(a+|b)?/i
+    AB
+ 0: A
+ 1: A
+
+/(a+|b){0,1}/i
+    AB
+ 0: A
+ 1: A
+
+/(a+|b){0,1}?/i
+    AB
+ 0: 
+
+/[^ab]*/i
+    CDE
+ 0: CDE
+
+/abc/i
+
+/a*/i
+    
+
+/([abc])*d/i
+    ABBBCD
+ 0: ABBBCD
+ 1: C
+
+/([abc])*bcd/i
+    ABCD
+ 0: ABCD
+ 1: A
+
+/a|b|c|d|e/i
+    E
+ 0: E
+
+/(a|b|c|d|e)f/i
+    EF
+ 0: EF
+ 1: E
+
+/abcd*efg/i
+    ABCDEFG
+ 0: ABCDEFG
+
+/ab*/i
+    XABYABBBZ
+ 0: AB
+    XAYABBBZ
+ 0: A
+
+/(ab|cd)e/i
+    ABCDE
+ 0: CDE
+ 1: CD
+
+/[abhgefdc]ij/i
+    HIJ
+ 0: HIJ
+
+/^(ab|cd)e/i
+    ABCDE
+No match
+
+/(abc|)ef/i
+    ABCDEF
+ 0: EF
+ 1: 
+
+/(a|b)c*d/i
+    ABCD
+ 0: BCD
+ 1: B
+
+/(ab|ab*)bc/i
+    ABC
+ 0: ABC
+ 1: A
+
+/a([bc]*)c*/i
+    ABC
+ 0: ABC
+ 1: BC
+
+/a([bc]*)(c*d)/i
+    ABCD
+ 0: ABCD
+ 1: BC
+ 2: D
+
+/a([bc]+)(c*d)/i
+    ABCD
+ 0: ABCD
+ 1: BC
+ 2: D
+
+/a([bc]*)(c+d)/i
+    ABCD
+ 0: ABCD
+ 1: B
+ 2: CD
+
+/a[bcd]*dcdcde/i
+    ADCDCDE
+ 0: ADCDCDE
+
+/a[bcd]+dcdcde/i
+
+/(ab|a)b*c/i
+    ABC
+ 0: ABC
+ 1: AB
+
+/((a)(b)c)(d)/i
+    ABCD
+ 0: ABCD
+ 1: ABC
+ 2: A
+ 3: B
+ 4: D
+
+/[a-zA-Z_][a-zA-Z0-9_]*/i
+    ALPHA
+ 0: ALPHA
+
+/^a(bc+|b[eh])g|.h$/i
+    ABH
+ 0: BH
+
+/(bc+d$|ef*g.|h?i(j|k))/i
+    EFFGZ
+ 0: EFFGZ
+ 1: EFFGZ
+    IJ
+ 0: IJ
+ 1: IJ
+ 2: J
+    REFFGZ
+ 0: EFFGZ
+ 1: EFFGZ
+    *** Failers
+No match
+    ADCDCDE
+No match
+    EFFG
+No match
+    BCDD
+No match
+
+/((((((((((a))))))))))/i
+    A
+ 0: A
+ 1: A
+ 2: A
+ 3: A
+ 4: A
+ 5: A
+ 6: A
+ 7: A
+ 8: A
+ 9: A
+10: A
+
+/((((((((((a))))))))))\10/i
+    AA
+ 0: AA
+ 1: A
+ 2: A
+ 3: A
+ 4: A
+ 5: A
+ 6: A
+ 7: A
+ 8: A
+ 9: A
+10: A
+
+/(((((((((a)))))))))/i
+    A
+ 0: A
+ 1: A
+ 2: A
+ 3: A
+ 4: A
+ 5: A
+ 6: A
+ 7: A
+ 8: A
+ 9: A
+
+/(?:(?:(?:(?:(?:(?:(?:(?:(?:(a))))))))))/i
+    A
+ 0: A
+ 1: A
+
+/(?:(?:(?:(?:(?:(?:(?:(?:(?:(a|b|c))))))))))/i
+    C
+ 0: C
+ 1: C
+
+/multiple words of text/i
+    *** Failers
+No match
+    AA
+No match
+    UH-UH
+No match
+
+/multiple words/i
+    MULTIPLE WORDS, YEAH
+ 0: MULTIPLE WORDS
+
+/(.*)c(.*)/i
+    ABCDE
+ 0: ABCDE
+ 1: AB
+ 2: DE
+
+/\((.*), (.*)\)/i
+    (A, B)
+ 0: (A, B)
+ 1: A
+ 2: B
+
+/[k]/i
+
+/abcd/i
+    ABCD
+ 0: ABCD
+
+/a(bc)d/i
+    ABCD
+ 0: ABCD
+ 1: BC
+
+/a[-]?c/i
+    AC
+ 0: AC
+
+/(abc)\1/i
+    ABCABC
+ 0: ABCABC
+ 1: ABC
+
+/([a-c]*)\1/i
+    ABCABC
+ 0: ABCABC
+ 1: ABC
+
+/a(?!b)./
+    abad
+ 0: ad
+
+/a(?=d)./
+    abad
+ 0: ad
+
+/a(?=c|d)./
+    abad
+ 0: ad
+
+/a(?:b|c|d)(.)/
+    ace
+ 0: ace
+ 1: e
+
+/a(?:b|c|d)*(.)/
+    ace
+ 0: ace
+ 1: e
+
+/a(?:b|c|d)+?(.)/
+    ace
+ 0: ace
+ 1: e
+    acdbcdbe
+ 0: acd
+ 1: d
+
+/a(?:b|c|d)+(.)/
+    acdbcdbe
+ 0: acdbcdbe
+ 1: e
+
+/a(?:b|c|d){2}(.)/
+    acdbcdbe
+ 0: acdb
+ 1: b
+
+/a(?:b|c|d){4,5}(.)/
+    acdbcdbe
+ 0: acdbcdb
+ 1: b
+
+/a(?:b|c|d){4,5}?(.)/
+    acdbcdbe
+ 0: acdbcd
+ 1: d
+
+/((foo)|(bar))*/
+    foobar
+ 0: foobar
+ 1: bar
+ 2: foo
+ 3: bar
+
+/a(?:b|c|d){6,7}(.)/
+    acdbcdbe
+ 0: acdbcdbe
+ 1: e
+
+/a(?:b|c|d){6,7}?(.)/
+    acdbcdbe
+ 0: acdbcdbe
+ 1: e
+
+/a(?:b|c|d){5,6}(.)/
+    acdbcdbe
+ 0: acdbcdbe
+ 1: e
+
+/a(?:b|c|d){5,6}?(.)/
+    acdbcdbe
+ 0: acdbcdb
+ 1: b
+
+/a(?:b|c|d){5,7}(.)/
+    acdbcdbe
+ 0: acdbcdbe
+ 1: e
+
+/a(?:b|c|d){5,7}?(.)/
+    acdbcdbe
+ 0: acdbcdb
+ 1: b
+
+/a(?:b|(c|e){1,2}?|d)+?(.)/
+    ace
+ 0: ace
+ 1: c
+ 2: e
+
+/^(.+)?B/
+    AB
+ 0: AB
+ 1: A
+
+/^([^a-z])|(\^)$/
+    .
+ 0: .
+ 1: .
+
+/^[<>]&/
+    <&OUT
+ 0: <&
+
+/^(a\1?){4}$/
+    aaaaaaaaaa
+ 0: aaaaaaaaaa
+ 1: aaaa
+    *** Failers
+No match
+    AB
+No match
+    aaaaaaaaa
+No match
+    aaaaaaaaaaa
+No match
+
+/^(a(?(1)\1)){4}$/
+    aaaaaaaaaa
+ 0: aaaaaaaaaa
+ 1: aaaa
+    *** Failers
+No match
+    aaaaaaaaa
+No match
+    aaaaaaaaaaa
+No match
+
+/(?:(f)(o)(o)|(b)(a)(r))*/
+    foobar
+ 0: foobar
+ 1: f
+ 2: o
+ 3: o
+ 4: b
+ 5: a
+ 6: r
+
+/(?<=a)b/
+    ab
+ 0: b
+    *** Failers
+No match
+    cb
+No match
+    b
+No match
+
+/(?<!c)b/
+    ab
+ 0: b
+    b
+ 0: b
+    b
+ 0: b
+
+/(?:..)*a/
+    aba
+ 0: aba
+
+/(?:..)*?a/
+    aba
+ 0: a
+
+/^(?:b|a(?=(.)))*\1/
+    abc
+ 0: ab
+ 1: b
+
+/^(){3,5}/
+    abc
+ 0: 
+ 1: 
+
+/^(a+)*ax/
+    aax
+ 0: aax
+ 1: a
+
+/^((a|b)+)*ax/
+    aax
+ 0: aax
+ 1: a
+ 2: a
+
+/^((a|bc)+)*ax/
+    aax
+ 0: aax
+ 1: a
+ 2: a
+
+/(a|x)*ab/
+    cab
+ 0: ab
+
+/(a)*ab/
+    cab
+ 0: ab
+
+/(?:(?i)a)b/
+    ab
+ 0: ab
+
+/((?i)a)b/
+    ab
+ 0: ab
+ 1: a
+
+/(?:(?i)a)b/
+    Ab
+ 0: Ab
+
+/((?i)a)b/
+    Ab
+ 0: Ab
+ 1: A
+
+/(?:(?i)a)b/
+    *** Failers
+No match
+    cb
+No match
+    aB
+No match
+
+/((?i)a)b/
+
+/(?i:a)b/
+    ab
+ 0: ab
+
+/((?i:a))b/
+    ab
+ 0: ab
+ 1: a
+
+/(?i:a)b/
+    Ab
+ 0: Ab
+
+/((?i:a))b/
+    Ab
+ 0: Ab
+ 1: A
+
+/(?i:a)b/
+    *** Failers
+No match
+    aB
+No match
+    aB
+No match
+
+/((?i:a))b/
+
+/(?:(?-i)a)b/i
+    ab
+ 0: ab
+
+/((?-i)a)b/i
+    ab
+ 0: ab
+ 1: a
+
+/(?:(?-i)a)b/i
+    aB
+ 0: aB
+
+/((?-i)a)b/i
+    aB
+ 0: aB
+ 1: a
+
+/(?:(?-i)a)b/i
+    *** Failers
+No match
+    aB
+ 0: aB
+    Ab
+No match
+
+/((?-i)a)b/i
+
+/(?:(?-i)a)b/i
+    aB
+ 0: aB
+
+/((?-i)a)b/i
+    aB
+ 0: aB
+ 1: a
+
+/(?:(?-i)a)b/i
+    *** Failers
+No match
+    Ab
+No match
+    AB
+No match
+
+/((?-i)a)b/i
+
+/(?-i:a)b/i
+    ab
+ 0: ab
+
+/((?-i:a))b/i
+    ab
+ 0: ab
+ 1: a
+
+/(?-i:a)b/i
+    aB
+ 0: aB
+
+/((?-i:a))b/i
+    aB
+ 0: aB
+ 1: a
+
+/(?-i:a)b/i
+    *** Failers
+No match
+    AB
+No match
+    Ab
+No match
+
+/((?-i:a))b/i
+
+/(?-i:a)b/i
+    aB
+ 0: aB
+
+/((?-i:a))b/i
+    aB
+ 0: aB
+ 1: a
+
+/(?-i:a)b/i
+    *** Failers
+No match
+    Ab
+No match
+    AB
+No match
+
+/((?-i:a))b/i
+
+/((?-i:a.))b/i
+    *** Failers
+No match
+    AB
+No match
+    a\nB
+No match
+
+/((?s-i:a.))b/i
+    a\nB
+ 0: a\x0aB
+ 1: a\x0a
+
+/(?:c|d)(?:)(?:a(?:)(?:b)(?:b(?:))(?:b(?:)(?:b)))/
+    cabbbb
+ 0: cabbbb
+
+/(?:c|d)(?:)(?:aaaaaaaa(?:)(?:bbbbbbbb)(?:bbbbbbbb(?:))(?:bbbbbbbb(?:)(?:bbbbbbbb)))/
+    caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+ 0: caaaaaaaabbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb
+
+/(ab)\d\1/i
+    Ab4ab
+ 0: Ab4ab
+ 1: Ab
+    ab4Ab
+ 0: ab4Ab
+ 1: ab
+
+/foo\w*\d{4}baz/
+    foobar1234baz
+ 0: foobar1234baz
+
+/x(~~)*(?:(?:F)?)?/
+    x~~
+ 0: x~~
+ 1: ~~
+
+/^a(?#xxx){3}c/
+    aaac
+ 0: aaac
+
+/^a (?#xxx) (?#yyy) {3}c/x
+    aaac
+ 0: aaac
+
+/(?<![cd])b/
+    *** Failers
+No match
+    B\nB
+No match
+    dbcb
+No match
+
+/(?<![cd])[ab]/
+    dbaacb
+ 0: a
+
+/(?<!(c|d))b/
+
+/(?<!(c|d))[ab]/
+    dbaacb
+ 0: a
+
+/(?<!cd)[ab]/
+    cdaccb
+ 0: b
+
+/^(?:a?b?)*$/
+    *** Failers
+No match
+    dbcb
+No match
+    a--
+No match
+
+/((?s)^a(.))((?m)^b$)/
+    a\nb\nc\n
+ 0: a\x0ab
+ 1: a\x0a
+ 2: \x0a
+ 3: b
+
+/((?m)^b$)/
+    a\nb\nc\n
+ 0: b
+ 1: b
+
+/(?m)^b/
+    a\nb\n
+ 0: b
+
+/(?m)^(b)/
+    a\nb\n
+ 0: b
+ 1: b
+
+/((?m)^b)/
+    a\nb\n
+ 0: b
+ 1: b
+
+/\n((?m)^b)/
+    a\nb\n
+ 0: \x0ab
+ 1: b
+
+/((?s).)c(?!.)/
+    a\nb\nc\n
+ 0: \x0ac
+ 1: \x0a
+    a\nb\nc\n
+ 0: \x0ac
+ 1: \x0a
+
+/((?s)b.)c(?!.)/
+    a\nb\nc\n
+ 0: b\x0ac
+ 1: b\x0a
+    a\nb\nc\n
+ 0: b\x0ac
+ 1: b\x0a
+
+/^b/
+
+/()^b/
+    *** Failers
+No match
+    a\nb\nc\n
+No match
+    a\nb\nc\n
+No match
+
+/((?m)^b)/
+    a\nb\nc\n
+ 0: b
+ 1: b
+
+/(?(1)a|b)/
+
+/(?(1)b|a)/
+    a
+ 0: a
+
+/(x)?(?(1)a|b)/
+    *** Failers
+No match
+    a
+No match
+    a
+No match
+
+/(x)?(?(1)b|a)/
+    a
+ 0: a
+
+/()?(?(1)b|a)/
+    a
+ 0: a
+
+/()(?(1)b|a)/
+
+/()?(?(1)a|b)/
+    a
+ 0: a
+ 1: 
+
+/^(\()?blah(?(1)(\)))$/
+    (blah)
+ 0: (blah)
+ 1: (
+ 2: )
+    blah
+ 0: blah
+    *** Failers
+No match
+    a
+No match
+    blah)
+No match
+    (blah
+No match
+
+/^(\(+)?blah(?(1)(\)))$/
+    (blah)
+ 0: (blah)
+ 1: (
+ 2: )
+    blah
+ 0: blah
+    *** Failers
+No match
+    blah)
+No match
+    (blah
+No match
+
+/(?(?!a)a|b)/
+
+/(?(?!a)b|a)/
+    a
+ 0: a
+
+/(?(?=a)b|a)/
+    *** Failers
+No match
+    a
+No match
+    a
+No match
+
+/(?(?=a)a|b)/
+    a
+ 0: a
+
+/(?=(a+?))(\1ab)/
+    aaab
+ 0: aab
+ 1: a
+ 2: aab
+
+/^(?=(a+?))\1ab/
+
+/(\w+:)+/
+    one:
+ 0: one:
+ 1: one:
+
+/$(?<=^(a))/
+    a
+ 0: 
+ 1: a
+
+/(?=(a+?))(\1ab)/
+    aaab
+ 0: aab
+ 1: a
+ 2: aab
+
+/^(?=(a+?))\1ab/
+    *** Failers
+No match
+    aaab
+No match
+    aaab
+No match
+
+/([\w:]+::)?(\w+)$/
+    abcd
+ 0: abcd
+ 1: <unset>
+ 2: abcd
+    xy:z:::abcd
+ 0: xy:z:::abcd
+ 1: xy:z:::
+ 2: abcd
+
+/^[^bcd]*(c+)/
+    aexycd
+ 0: aexyc
+ 1: c
+
+/(a*)b+/
+    caab
+ 0: aab
+ 1: aa
+
+/([\w:]+::)?(\w+)$/
+    abcd
+ 0: abcd
+ 1: <unset>
+ 2: abcd
+    xy:z:::abcd
+ 0: xy:z:::abcd
+ 1: xy:z:::
+ 2: abcd
+    *** Failers
+ 0: Failers
+ 1: <unset>
+ 2: Failers
+    abcd:
+No match
+    abcd:
+No match
+
+/^[^bcd]*(c+)/
+    aexycd
+ 0: aexyc
+ 1: c
+
+/(>a+)ab/
+
+/(?>a+)b/
+    aaab
+ 0: aaab
+
+/([[:]+)/
+    a:[b]:
+ 0: :[
+ 1: :[
+
+/([[=]+)/
+    a=[b]=
+ 0: =[
+ 1: =[
+
+/([[.]+)/
+    a.[b].
+ 0: .[
+ 1: .[
+
+/((?>a+)b)/
+    aaab
+ 0: aaab
+ 1: aaab
+
+/(?>(a+))b/
+    aaab
+ 0: aaab
+ 1: aaa
+
+/((?>[^()]+)|\([^()]*\))+/
+    ((abc(ade)ufh()()x
+ 0: abc(ade)ufh()()x
+ 1: x
+
+/a\Z/
+    *** Failers
+No match
+    aaab
+No match
+    a\nb\n
+No match
+
+/b\Z/
+    a\nb\n
+ 0: b
+
+/b\z/
+
+/b\Z/
+    a\nb
+ 0: b
+
+/b\z/
+    a\nb
+ 0: b
+    *** Failers
+No match
+    
+/^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$/
+    a
+ 0: a
+ 1: 
+    abc
+ 0: abc
+ 1: 
+    a-b
+ 0: a-b
+ 1: 
+    0-9 
+ 0: 0-9
+ 1: 
+    a.b
+ 0: a.b
+ 1: 
+    5.6.7  
+ 0: 5.6.7
+ 1: 
+    the.quick.brown.fox
+ 0: the.quick.brown.fox
+ 1: 
+    a100.b200.300c  
+ 0: a100.b200.300c
+ 1: 
+    12-ab.1245 
+ 0: 12-ab.1245
+ 1: 
+    ***Failers
+No match
+    \
+No match
+    .a
+No match
+    -a
+No match
+    a-
+No match
+    a.  
+No match
+    a_b 
+No match
+    a.-
+No match
+    a..  
+No match
+    ab..bc 
+No match
+    the.quick.brown.fox-
+No match
+    the.quick.brown.fox.
+No match
+    the.quick.brown.fox_
+No match
+    the.quick.brown.fox+       
+No match
+
+/(?>.*)(?<=(abcd|wxyz))/
+    alphabetabcd
+ 0: alphabetabcd
+ 1: abcd
+    endingwxyz
+ 0: endingwxyz
+ 1: wxyz
+    *** Failers
+No match
+    a rather long string that doesn't end with one of them
+No match
+
+/word (?>(?:(?!otherword)[a-zA-Z0-9]+ ){0,30})otherword/
+    word cat dog elephant mussel cow horse canary baboon snake shark otherword
+ 0: word cat dog elephant mussel cow horse canary baboon snake shark otherword
+    word cat dog elephant mussel cow horse canary baboon snake shark
+No match
+  
+/word (?>[a-zA-Z0-9]+ ){0,30}otherword/
+    word cat dog elephant mussel cow horse canary baboon snake shark the quick brown fox and the lazy dog and several other words getting close to thirty by now I hope
+No match
+
+/(?<=\d{3}(?!999))foo/
+    999foo
+ 0: foo
+    123999foo 
+ 0: foo
+    *** Failers
+No match
+    123abcfoo
+No match
+    
+/(?<=(?!...999)\d{3})foo/
+    999foo
+ 0: foo
+    123999foo 
+ 0: foo
+    *** Failers
+No match
+    123abcfoo
+No match
+
+/(?<=\d{3}(?!999)...)foo/
+    123abcfoo
+ 0: foo
+    123456foo 
+ 0: foo
+    *** Failers
+No match
+    123999foo  
+No match
+    
+/(?<=\d{3}...)(?<!999)foo/
+    123abcfoo   
+ 0: foo
+    123456foo 
+ 0: foo
+    *** Failers
+No match
+    123999foo  
+No match
+
+/<a[\s]+href[\s]*=[\s]*          # find <a href=
+ ([\"\'])?                       # find single or double quote
+ (?(1) (.*?)\1 | ([^\s]+))       # if quote found, match up to next matching
+                                 # quote, otherwise match up to next space
+/isx
+    <a href=abcd xyz
+ 0: <a href=abcd
+ 1: <unset>
+ 2: <unset>
+ 3: abcd
+    <a href=\"abcd xyz pqr\" cats
+ 0: <a href="abcd xyz pqr"
+ 1: "
+ 2: abcd xyz pqr
+    <a href=\'abcd xyz pqr\' cats
+ 0: <a href='abcd xyz pqr'
+ 1: '
+ 2: abcd xyz pqr
+
+/<a\s+href\s*=\s*                # find <a href=
+ (["'])?                         # find single or double quote
+ (?(1) (.*?)\1 | (\S+))          # if quote found, match up to next matching
+                                 # quote, otherwise match up to next space
+/isx
+    <a href=abcd xyz
+ 0: <a href=abcd
+ 1: <unset>
+ 2: <unset>
+ 3: abcd
+    <a href=\"abcd xyz pqr\" cats
+ 0: <a href="abcd xyz pqr"
+ 1: "
+ 2: abcd xyz pqr
+    <a href       =       \'abcd xyz pqr\' cats
+ 0: <a href       =       'abcd xyz pqr'
+ 1: '
+ 2: abcd xyz pqr
+
+/<a\s+href(?>\s*)=(?>\s*)        # find <a href=
+ (["'])?                         # find single or double quote
+ (?(1) (.*?)\1 | (\S+))          # if quote found, match up to next matching
+                                 # quote, otherwise match up to next space
+/isx
+    <a href=abcd xyz
+ 0: <a href=abcd
+ 1: <unset>
+ 2: <unset>
+ 3: abcd
+    <a href=\"abcd xyz pqr\" cats
+ 0: <a href="abcd xyz pqr"
+ 1: "
+ 2: abcd xyz pqr
+    <a href       =       \'abcd xyz pqr\' cats
+ 0: <a href       =       'abcd xyz pqr'
+ 1: '
+ 2: abcd xyz pqr
+
+/ End of test input /       
+
diff --git a/ext/pcre/pcrelib/testdata/testoutput4 b/ext/pcre/pcrelib/testdata/testoutput4
new file mode 100644 (file)
index 0000000..d951b48
--- /dev/null
@@ -0,0 +1,115 @@
+PCRE version 3.1 09-Feb-2000
+
+/^[\w]+/
+    *** Failers
+No match
+    École
+No match
+
+/^[\w]+/Lfr
+    École
+ 0: École
+
+/^[\w]+/
+    *** Failers
+No match
+    École
+No match
+
+/^[\W]+/
+    École
+ 0: \xc9
+
+/^[\W]+/Lfr
+    *** Failers
+ 0: *** 
+    École
+No match
+
+/[\b]/
+    \b
+ 0: \x08
+    *** Failers
+No match
+    a
+No match
+
+/[\b]/Lfr
+    \b
+ 0: \x08
+    *** Failers
+No match
+    a
+No match
+
+/^\w+/
+    *** Failers
+No match
+    École
+No match
+
+/^\w+/Lfr
+    École
+ 0: École
+
+/(.+)\b(.+)/
+    École
+ 0: \xc9cole
+ 1: \xc9
+ 2: cole
+
+/(.+)\b(.+)/Lfr
+    *** Failers
+ 0: *** Failers
+ 1: *** 
+ 2: Failers
+    École
+No match
+
+/École/i
+    École
+ 0: \xc9cole
+    *** Failers
+No match
+    école
+No match
+
+/École/iLfr
+    École
+ 0: École
+    école
+ 0: école
+
+/\w/IS
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Starting character set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P 
+  Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z 
+
+/\w/ISLfr
+Capturing subpattern count = 0
+No options
+No first char
+No need char
+Starting character set: 0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P 
+  Q R S T U V W X Y Z _ a b c d e f g h i j k l m n o p q r s t u v w x y z 
+  À Á Â Ã Ä Å Æ Ç È É Ê Ë Ì Í Î Ï Ð Ñ Ò Ó Ô Õ Ö Ø Ù Ú Û Ü Ý Þ ß à á â ã ä å 
+  æ ç è é ê ë ì í î ï ð ñ ò ó ô õ ö ø ù ú û ü ý þ ÿ 
+
+/^[\xc8-\xc9]/iLfr
+    École
+ 0: É
+    école
+ 0: é
+
+/^[\xc8-\xc9]/Lfr
+    École
+ 0: É
+    *** Failers 
+No match
+    école
+No match
+
+