Regexp-Common-Apache2/lib/Regexp/Common/Apache2.pm
##----------------------------------------------------------------------------
## Module Generic - ~/scripts/Apache2.pm
## Version v0.2.1
## Copyright(c) 2021 DEGUEST Pte. Ltd.
## Author: Jacques Deguest <jack@deguest.jp>
## Created 2021/02/14
## Modified 2021/03/07
## All rights reserved
##
## This program is free software; you can redistribute it and/or modify it
## under the same terms as Perl itself.
##----------------------------------------------------------------------------
package Regexp::Common::Apache2;
BEGIN
{
use strict;
use warnings;
use warnings::register;
use parent qw( Exporter );
use Regexp::Common qw( pattern );
our $VERSION = 'v0.2.1';
our $DEBUG = 3;
## Ref: <http://httpd.apache.org/docs/trunk/en/expr.html>
our $UNARY_OP = qr/(?:(?<=\W)|(?<=^)|(?<=\A))\-[a-zA-Z]/;
our $DIGIT = qr/[0-9]/;
our $REGPATTERN = qr/(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+/;
our $REGFLAGS = qr/[i|s|m|g]+/;
our $REGSEP = qr/[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-]/;
our $FUNCNAME = qr/[a-zA-Z_]\w*/;
our $VARNAME = qr/[a-zA-Z_]\w*/;
our $TEXT = qr/[^[:cntrl:]]/;
## See Regexp::Common::net
our $IPv4 = qr/(?:(?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})[.](?:25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))/;
our $IPv6 = qr/(?:(?|(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4})|(?::(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?::(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?::(?:)(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?::(?:)(?:)(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?::(?:)(?:)(?:)(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?::(?:)(?:)(?:)(?:)(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}))|(?::(?:)(?:)(?:)(?:)(?:)(?:)(?:)(?:):)|(?:(?:[0-9a-fA-F]{1,4}):(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:)(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:)(?:)(?:)(?:)(?:):)|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:)(?:)(?:)(?:):)|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:)(?:)(?:):)|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:)(?:):)|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:):(?:[0-9a-fA-F]{1,4}))|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:)(?:):)|(?:(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:[0-9a-fA-F]{1,4}):(?:)(?:):)))/;
##our $ap_true = do{ bless( \( my $dummy = 1 ) => "Regexp::Common::Apache2::Boolean" ) };
##our $ap_false = do{ bless( \( my $dummy = 0 ) => "Regexp::Common::Apache2::Boolean" ) };
our $ap_true = 1;
our $ap_false = 0;
our @EXPORT_OK = qw( $ap_true $ap_false );
our $REGEXP = {};
our $TRUNK = {};
## Legacy regular expression
## <http://httpd.apache.org/docs/trunk/en/mod/mod_include.html#legacyexpr>
our $REGEXP_LEGACY = {};
$REGEXP =
{
unary_op => $UNARY_OP,
## <any US-ASCII digit "0".."9">
digit => $DIGIT,
## 1*(DIGIT)
digits => qr/${DIGIT}{1,}/,
## "$" DIGIT
## As per Apache apr_expr documentation, regular expression back reference go from 1 to 9 with 0 containing the entire regexp
rebackref => qr/(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})/,
## cstring ; except enclosing regsep
regpattern => $REGPATTERN,
## 1*("i" | "s" | "m" | "g")
regflags => $REGFLAGS,
## "/" | "#" | "$" | "%" | "^" | "|" | "?" | "!" | "'" | '"' | "," | ";" | ":" | "." | "_" | "-"
regsep => $REGSEP,
## "/" regpattern "/" [regflags]
## | "m" regsep regpattern regsep [regflags]
regex => qr/
(?<regex>
(?:(?<regsep>\/)(?<regpattern>${REGPATTERN})\/(?<regflags>${REGFLAGS})?)
|
(?:m(?<regsep>${REGSEP})(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>${REGFLAGS})?)
)/x,
funcname => $FUNCNAME,
varname => $VARNAME,
## <any OCTET except CTLs>
text => $TEXT,
## 0*(TEXT)
cstring => qr/[^[:cntrl:]]+/,
true => qr/[1]/,
false => qr/[0]/,
ipaddr => qr/(?:$IPv4|$IPv6)/,
};
$REGEXP->{is_true} = qr/
(?:
(?:\btrue\b)
|
(?:
(?:(?<=\W)|(?<=\A)|(?<=^))$Regexp::Common::Apache2::REGEXP->{true}(?=\W|\Z|$)
)
)
/x;
$REGEXP->{is_false} = qr/
(?:
(?:\bfalse\b)
|
(?:
(?:(?<=\W)|(?<=\A)|(?<=^))$Regexp::Common::Apache2::REGEXP->{false}(?=\W|\Z|$)
)
)
/x;
## stringcomp
## | integercomp
## | unaryop word
## | word binaryop word
## | word "in" listfunc
## | word "=~" regex
## | word "!~" regex
## | word "in" "{" list "}"
## Ref:
## <http://httpd.apache.org/docs/trunk/en/expr.html#unnop>
## <http://httpd.apache.org/docs/trunk/en/expr.html#binop>
$REGEXP->{comp} = qr/
(?<comp>
(?:
(?<comp_stringcomp> (?&stringcomp) )
)
|
(?:
(?<comp_integercomp> (?&integercomp) )
)
|
(?<comp_unary>
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<comp_unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_word> (?&word) )
)
|
(?<comp_binary>
(?<comp_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<comp_binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<comp_binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_wordb> (?&word_lax) )
)
|
(?<comp_word_in_listfunc>
(?<comp_word> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_listfunc> (?&listfunc) )
)
|
(?<comp_word_in_regexp>
(?<comp_word> (?&word) )
[[:blank:]\h]+
(?<comp_regexp_op> [\=|\!]\~ )
[[:blank:]\h]+
(?<comp_regexp>$Regexp::Common::Apache2::REGEXP->{regex})
)
|
(?<comp_word_in_list>
(?<comp_word> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?(DEFINE)
(?<comp_recur>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<unary_word>(?&word_lax))
)
)
|
(?:
(?<binary_worda>(?&word_lax))
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<binary_worda>(?&word_lax))
)
|
(?:
(?<funclist_worda> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<funclist_list> (?&listfunc) )
)
|
(?:
(?<regex_word> (?&word) )
[[:blank:]\h]+
[\=|\!]\~
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<list_word> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
|
(?:
( # paren group 1 (full function)
(?<func_name>[a-zA-Z_]\w*)? # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
( # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?:(?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_backref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## "true"
## | "false"
## | "!" cond
## | cond "&&" cond
## | cond "||" cond
## | "(" cond ")"
## | comp
$REGEXP->{cond} = qr/
(?<cond>
(?:
(?<cond_true>$Regexp::Common::Apache2::REGEXP->{is_true})
)
|
(?:
(?<cond_false>$Regexp::Common::Apache2::REGEXP->{is_false})
)
|
(?:
(?:
\(
[[:blank:]\h]*
(?<cond_parenthesis>
(?&cond_recur)
)
[[:blank:]\h]*
\)
)
)
|
(?:
(?<cond_neg>\![[:blank:]\h]*(?<cond_expr>(?&cond_recur)))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and>
(?<cond_and_expr1>
(?: (?&cond_recur) )+
)
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2>
(?: (?&cond_recur) )+
)
)
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or>
(?<cond_or_expr1>
(?: (?&cond_recur) )+
)
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2>
(?: (?&cond_recur) )+
)
)
)
)
|
(?:
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<unary_word>(?&word_lax))
)
)
|
(?:
(?<binary_worda>(?&word_lax))
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<binary_worda>(?&word_lax))
)
|
(?:
(?<funclist_worda> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<funclist_list> (?&listfunc) )
)
|
(?:
(?<regex_word> (?&word) )
[[:blank:]\h]+
[\=|\!]\~
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<list_word> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<cond_recur>
(?:$Regexp::Common::Apache2::REGEXP->{is_true})
|
(?:$Regexp::Common::Apache2::REGEXP->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<enclosed_cond> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_bool_and>
(?<cond_bool_or_expr1> (?: (?-3) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_bool_or_expr2> (?: (?-3) )+ )
)
)
|
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_bool_and>
(?<cond_bool_and_expr1> (?: (?-3) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_bool_and_expr2> (?: (?-3) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
|
(?:
( # paren group 1 (full function)
(?<func_name>[a-zA-Z_]\w*)? # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
( # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?:(?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_backref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/xi;
## cond
## | string
$REGEXP->{expr} = qr/
(?<expr>
(?:
(?<expr_cond>(?&cond))
)
|
(?:
(?<expr_string>(?&string))
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<unary_word>(?&word_lax))
)
)
|
(?:
(?<binary_worda>(?&word_lax))
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<binary_worda>(?&word_lax))
)
|
(?:
(?<funclist_worda> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<funclist_list> (?&listfunc) )
)
|
(?:
(?<regex_word> (?&word) )
[[:blank:]\h]+
[\=|\!]\~
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<list_word> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::REGEXP->{is_true})
|
(?:$Regexp::Common::Apache2::REGEXP->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<enclosed_cond> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_bool_and>
(?<cond_bool_or_expr1> (?: (?-3) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_bool_or_expr2> (?: (?-3) )+ )
)
)
|
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_bool_and>
(?<cond_bool_and_expr1> (?: (?-3) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_bool_and_expr2> (?: (?-3) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
|
(?:
( # paren group 1 (full function)
(?<func_name>[a-zA-Z_]\w*)? # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
( # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?:(?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_backref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## funcname "(" words ")"
## -> Same as LISTFUNC
$REGEXP->{function} = qr/
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<unary_word>(?&word_lax))
)
)
|
(?:
(?<binary_worda>(?&word_lax))
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<binary_worda>(?&word_lax))
)
|
(?:
(?<funclist_worda> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<funclist_list> (?&listfunc) )
)
|
(?:
(?<regex_word> (?&word) )
[[:blank:]\h]+
[\=|\!]\~
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<list_word> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function_recur>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
|
(?:
( # paren group 1 (full function)
(?<func_name>[a-zA-Z_]\w*)? # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
( # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?:(?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_backref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function_recur))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function_recur))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## word "-eq" word | word "eq" word
## | word "-ne" word | word "ne" word
## | word "-lt" word | word "lt" word
## | word "-le" word | word "le" word
## | word "-gt" word | word "gt" word
## | word "-ge" word | word "ge" word
$REGEXP->{integercomp} = qr/
(?<integercomp>
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op>eq|ne|lt|le|gt|ge)
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_integercomp>
(?&integercomp_recur)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<unary_word>(?&word_lax))
)
)
|
(?:
(?<binary_worda>(?&word_lax))
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<binary_worda>(?&word_lax))
)
|
(?:
(?<funclist_worda> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<funclist_list> (?&listfunc) )
)
|
(?:
(?<regex_word> (?&word) )
[[:blank:]\h]+
[\=|\!]\~
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<list_word> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
|
(?:
( # paren group 1 (full function)
(?<func_name>[a-zA-Z_]\w*)? # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
( # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<integercomp_recur>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?:(?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_backref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## listfuncname "(" words ")"
## Use recursion at execution phase for words because it contains dependencies -> list -> listfunc
#(??{$Regexp::Common::Apache2::REGEXP->{words}})
$REGEXP->{listfunc} = qr/
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<unary_word>(?&word_lax))
)
)
|
(?:
(?<binary_worda>(?&word_lax))
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<binary_worda>(?&word_lax))
)
|
(?:
(?<funclist_worda> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<funclist_list> (?&listfunc_recur) )
)
|
(?:
(?<regex_word> (?&word) )
[[:blank:]\h]+
[\=|\!]\~
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<list_word> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::REGEXP->{is_true})
|
(?:$Regexp::Common::Apache2::REGEXP->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<enclosed_cond> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_bool_and>
(?<cond_bool_or_expr1> (?: (?-3) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_bool_or_expr2> (?: (?-3) )+ )
)
)
|
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_bool_and>
(?<cond_bool_and_expr1> (?: (?-3) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_bool_and_expr2> (?: (?-3) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
|
(?:
( # paren group 1 (full function)
(?<func_name>[a-zA-Z_]\w*)? # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
( # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc_recur>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?:(?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_backref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## substring
## | string substring
$REGEXP->{string} = qr/
(?<string>
(?:
(?&substring)
)
|
(?:
(?:(?&string_recur)[[:blank:]\h]+(?&substring))
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<unary_word>(?&word_lax))
)
)
|
(?:
(?<binary_worda>(?&word_lax))
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<binary_worda>(?&word_lax))
)
|
(?:
(?<funclist_worda> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<funclist_list> (?&listfunc) )
)
|
(?:
(?<regex_word> (?&word) )
[[:blank:]\h]+
[\=|\!]\~
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<list_word> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
|
(?:
( # paren group 1 (full function)
(?<func_name>[a-zA-Z_]\w*)? # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
( # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<string_recur>
(?:
(?: (?&substring) )
)
|
(?:
(?:(?&substring)[[:blank:]\h]+(?&string_recur) )
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_backref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
)
)
)/x;
## word "==" word
## | word "!=" word
## | word "<" word
## | word "<=" word
## | word ">" word
## | word ">=" word
$REGEXP->{stringcomp} = qr/
(?<stringcomp>
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_stringcomp>
(?&stringcomp_recur)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<unary_word>(?&word_lax))
)
)
|
(?:
(?<binary_worda>(?&word_lax))
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<binary_worda>(?&word_lax))
)
|
(?:
(?<funclist_worda> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<funclist_list> (?&listfunc) )
)
|
(?:
(?<regex_word> (?&word) )
[[:blank:]\h]+
[\=|\!]\~
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<list_word> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
|
(?:
( # paren group 1 (full function)
(?<func_name>[a-zA-Z_]\w*)? # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
( # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?:(?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp_recur>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_backref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## cstring
## | variable
## | rebackref
$REGEXP->{substring} = qr/
(?<substring>
(?:$Regexp::Common::Apache2::REGEXP->{cstring})
|
(?:
(?<sub_variable> (?&variable) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<unary_word>(?&word_lax))
)
)
|
(?:
(?<binary_worda>(?&word_lax))
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<binary_worda>(?&word_lax))
)
|
(?:
(?<funclist_worda> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<funclist_list> (?&listfunc) )
)
|
(?:
(?<regex_word> (?&word) )
[[:blank:]\h]+
[\=|\!]\~
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<list_word> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
|
(?:
( # paren group 1 (full function)
(?<func_name>[a-zA-Z_]\w*)? # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
( # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:(?-1)[[:blank:]\h]+(?&substring_recur))
|
(?&substring_recur)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring_recur>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_backref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## "%{" varname "}"
## | "%{" funcname ":" funcargs "}"
## | "v('" varname "')"
$REGEXP->{variable} = qr/
(?<variable>
(?:
(?:^|\A|(?<!\\))\%\{
(?:
(?<var_func>(?<var_func_name>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+))
)
\}
)
|
(?:
(?:^|\A|(?<!\\))\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<unary_word>(?&word_lax))
)
)
|
(?:
(?<binary_worda>(?&word_lax))
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<binary_worda>(?&word_lax))
)
|
(?:
(?<funclist_worda> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<funclist_list> (?&listfunc) )
)
|
(?:
(?<regex_word> (?&word) )
[[:blank:]\h]+
[\=|\!]\~
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<list_word> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
|
(?:
( # paren group 1 (full function)
(?<func_name>[a-zA-Z_]\w*)? # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
( # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?:(?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable_recur) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_backref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<variable_recur>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable_recur))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable_recur))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## digits
## | "'" string "'"
## | '"' string '"'
## | word "." word
## | variable
## | sub
## | join
## | function
## | "(" word ")"
$REGEXP->{word} = qr/
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?&word_recur)\. )+ (?&word_recur)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<unary_word>(?&word_lax))
)
)
|
(?:
(?<binary_worda>(?&word_lax))
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<binary_worda>(?&word_lax))
)
|
(?:
(?<funclist_worda> (?&word_recur) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<funclist_list> (?&listfunc) )
)
|
(?:
(?<regex_word> (?&word_recur) )
[[:blank:]\h]+
[\=|\!]\~
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<list_word> (?&word_recur) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
|
(?:
( # paren group 1 (full function)
(?<func_name>[a-zA-Z_]\w*)? # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
( # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word_recur))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word_recur))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?:(?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word_recur))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word_recur))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_backref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
)
(?<word_recur>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<words>
(?:
(?<words_list_word>
(?:
(?&word_recur)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word_recur)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word_recur) )
)?
)
|
(?:
(?<words_word> (?&word_recur) )
)
)
)
/x;
## word
## | word "," list
$REGEXP->{words} = qr/
(?<words>
(?:
(?<words_list>
(?<words_word>(?&word))
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_sublist>(?&words_recur))
)
)
|
(?:
(?<words_word>(?&word))
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<unary_word>(?&word_lax))
)
)
|
(?:
(?<binary_worda>(?&word_lax))
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<binary_worda>(?&word_lax))
)
|
(?:
(?<funclist_worda> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<funclist_list> (?&listfunc) )
)
|
(?:
(?<regex_word> (?&word) )
[[:blank:]\h]+
[\=|\!]\~
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<list_word> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
|
(?:
( # paren group 1 (full function)
(?<func_name>[a-zA-Z_]\w*)? # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
( # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?:(?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_backref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::REGEXP->{regex} )
)
)
(?<words_recur>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## Trunk regular expression
@$TRUNK{qw( unary_op digit digits rebackref regpattern regflags regsep regex funcname varname text cstring true false is_true is_false )} =
@$REGEXP{qw( unary_op digit digits rebackref regpattern regflags regsep regex funcname varname text cstring true false is_true is_false )};
## stringcomp
## | integercomp
## | unaryop word
## | word binaryop word
## | word "in" listfunc
## | word "=~" regex
## | word "!~" regex
## | word "in" "{" list "}"
## Ref:
## <http://httpd.apache.org/docs/trunk/en/expr.html#unnop>
## <http://httpd.apache.org/docs/trunk/en/expr.html#binop>
$TRUNK->{comp} = qr/
(?<comp>
(?:
(?<comp_stringcomp>(?&stringcomp))
)
|
(?:
(?<comp_integercomp>(?&integercomp))
)
|
(?<comp_unary>
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<comp_unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_word>(?&word))
)
|
(?<comp_binary>
(?<comp_worda>(?&word_lax))
[[:blank:]\h]+
(?:
(?<comp_binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<comp_binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_wordb>(?&word_lax))
)
|
(?<comp_word_in_listfunc>
(?<comp_word>(?&word))
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_listfunc>(?&listfunc))
)
|
(?<comp_word_in_regexp>
(?<comp_word>(?&word))
[[:blank:]\h]+
(?<comp_regexp_op>[\=|\!]\~)
[[:blank:]\h]+
(?<comp_regexp>$Regexp::Common::Apache2::TRUNK->{regex})
)
|
(?<comp_word_in_list>
(?<comp_word>(?&word))
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_list>(?&list))
[[:blank:]\h]*
\}
)
)
(?(DEFINE)
(?<comp_recur>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)
/x;
## "true"
## | "false"
## | "!" cond
## | cond "&&" cond
## | cond "||" cond
## | "(" cond ")"
## | comp
$TRUNK->{cond} = qr/
(?<cond>
(?:
(?<cond_true>$Regexp::Common::Apache2::TRUNK->{is_true})
)
|
(?:
(?<cond_false>$Regexp::Common::Apache2::TRUNK->{is_false})
)
|
(?:
(?:
\(
[[:blank:]\h]*
(?<cond_parenthesis>
(?&cond_recur)
)
[[:blank:]\h]*
\)
)
)
|
(?:
(?<cond_neg>\![[:blank:]\h]*(?<cond_expr>(?&cond_recur)))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and>
(?<cond_and_expr1>
(?: (?&cond_recur) )+
)
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2>
(?: (?&cond_recur) )+
)
)
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or>
(?<cond_or_expr1>
(?: (?&cond_recur) )+
)
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2>
(?: (?&cond_recur) )+
)
)
)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp> (?&comp) )
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond_recur>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (cond_recur) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)
/xi;
## cond
## | string
$TRUNK->{expr} = qr/
(?<expr>
(?:
(?<expr_cond>(?&cond))
)
|
(?:
(?<expr_string>(?&string))
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)
/x;
## funcname "(" words ")"
## -> Same as LISTFUNC
$TRUNK->{function} = qr/
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function_recur>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function_recur) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function_recur) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)
/x;
## word "-eq" word | word "eq" word
## | word "-ne" word | word "ne" word
## | word "-lt" word | word "lt" word
## | word "-le" word | word "le" word
## | word "-gt" word | word "gt" word
## | word "-ge" word | word "ge" word
$TRUNK->{integercomp} = qr/
(?<integercomp>
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op>eq|ne|lt|le|gt|ge)
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp_recur)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp_recur>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)
/x;
## "join" ["("] list [")"]
## | "join" ["("] list "," word [")"]
$TRUNK->{join} = qr/
(?<join>
join\(
[[:blank:]\h]*
(?:
(?:
(?<join_list>(?&list))[[:blank:]]*\,[[:blank:]]*(?<join_word>(?&word))
)
|
(?:
(?<join_list>(?&list))
)
)
[[:blank:]\h]*
\)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join_recur>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join_recur) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join_recur) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)
/x;
## split
## | listfunc
## | "{" words "}"
## | "(" list ")"
$TRUNK->{list} = qr/
(?<list>
(?:
(?<list_func>(?&listfunc))
)
|
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
(?<list_split>(?&split))
)
|
(?:
\(
[[:blank:]\h]*
(?<list_list> (?&list_recur) )
[[:blank:]\h]*
\)
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list_recur) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list_recur) )
)
[[:blank:]\h]*
\)
)
(?<list_recur>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list_recur) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list_recur) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)
/x;
## listfuncname "(" words ")"
## Use recursion at execution phase for words because it contains dependencies -> list -> listfunc
#(??{$Regexp::Common::Apache2::TRUNK->{words}})
$TRUNK->{listfunc} = qr/
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc_recur) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc_recur))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc_recur>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)
/x;
## regex | regsub
$TRUNK->{regany} = qr/
(?<regany>
(?:
(?<regany_regex>$Regexp::Common::Apache2::TRUNK->{regex})
|
(?:
(?<regany_regsub>(?®sub))
)
)
)
(?(DEFINE)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
)
/x;
## "s" regsep regpattern regsep string regsep [regflags]
$TRUNK->{regsub} = qr/
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
/x;
## "split" ["("] regany "," list [")"]
## | "split" ["("] regany "," word [")"]
$TRUNK->{split} = qr/
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word>(?&word))
)
|
(?:
(?<split_list>(?&list))
)
)
[[:blank:]\h]*
\)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split_recur))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split_recur>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)
/x;
## substring
## | string substring
$TRUNK->{string} = qr/
(?<string>
(?:
(?&substring)
)
|
(?:
(?:(?&string_recur)[[:blank:]\h]+(?&substring))
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string_recur>
(?:
(?:(?-1)[[:blank:]\h]+(?&substring))
)
|
(?:
(?: (?&substring) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string_recur) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)/x;
## word "==" word
## | word "!=" word
## | word "<" word
## | word "<=" word
## | word ">" word
## | word ">=" word
$TRUNK->{stringcomp} = qr/
(?<stringcomp>
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp_recur)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp_recur>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)
/x;
## "sub" ["("] regsub "," word [")"]
$TRUNK->{sub} = qr/
(?<sub>
sub\(
[[:blank:]\h]*
(?<sub_regsub>(?®sub))
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?:
(?<sub_word>
(?&word)
)
)
[[:blank:]\h]*
\)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub_recur>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub_recur) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub_recur) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)
/x;
## cstring
## | variable
$TRUNK->{substring} = qr/
(?<substring>
(?:$Regexp::Common::Apache2::TRUNK->{cstring})
|
(?:
(?<sub_variable> (?&variable) )
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?:(?-1)[[:blank:]\h]+(?&substring_recur))
)
|
(?:
(?: (?&substring_recur) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<substring_recur>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)
/x;
## "%{" varname "}"
## | "%{" funcname ":" funcargs "}"
## | "%{:" word ":}"
## | "%{:" cond ":}"
## | rebackref
$TRUNK->{variable} = qr/
(?<variable>
(?:
(?:^|\A|(?<!\\))\%\{
(?:
(?<var_func>(?<var_func_name>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+))
)
\}
)
|
(?:
(?:^|\A|(?<!\\))\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
(?:^|\A|(?<!\\))\%\{\:
(?(?=(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
(?:^|\A|(?<!\\))\%\{\:
(?:
(?<var_cond>(?&cond))
)
\:\}
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable_recur) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<variable_recur>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable_recur))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable_recur))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)
/x;
## digits
## | "'" string "'"
## | '"' string '"'
## | word "." word
## | variable
## | sub
## | join
## | function
## | "(" word ")"
$TRUNK->{word} = qr/
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::TRUNK->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_parens_open>\()
[[:blank:]\h]*
(?<word_enclosed>(?&word_lax))
[[:blank:]\h]*
(?<word_parens_close>\))
)
|
(?:
(?<word_dot_word> (?: (?&word_recur)\. )+ (?&word_recur) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_sub>(?&sub))
)
|
(?:
(?<word_join>(?&join))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
$Regexp::Common::Apache2::TRUNK->{regex}
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word_recur) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word_recur) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word_recur) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word_recur))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word_recur))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word_recur) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word_recur) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word_recur))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word_recur))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word_recur)) )
)
[[:blank:]\h]*
\)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word_recur) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word_recur>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word_recur) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word_recur)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word_recur)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word_recur) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word_recur) )
)
)
)
/x;
## word
## | word "," list
$TRUNK->{words} = qr/
(?<words>
(?:
(?:
(?<words_list_word>
(?:
(?<words_list_word1> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?<words_list_word2> (?&word) )
)
(?<words_list_more>
(?<words_list_sep>[[:blank:]\h]*\,[[:blank:]\h]*)
(?<words_word3> (?&word) )
)?
(?(<words_list_more>)
(?<words_list>\g{words_list_word}\g{words_list_more})
|
(?(<words_list_word1>)
(?<words_list>\g{words_list_word})
)
)
(?(<words_list>)
(?(<words_list_word1>)
(?<words_word> \g{words_list_word1} )
|
(?<words_word> \g{words_list_word2} )
)
|
(?(<words_list_word1>)
|
(?<words_word> \g{words_list_word2} )
)
)
(?(<words_list>)
(?(<words_list_more>)
(?(<words_list_word1>)
(?<words_sublist> \g{words_list_word2}\g{words_list_more} )
|
(?<words_sublist> \g{words_list_word1} )
)
|
(?<words_sublist> \g{words_list_word2} )
)
)
)
|
(?:
(?<words_list>
(?<words_word>(?&word))
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_sublist>(?&list))
)
)
|
(?:
(?<words_word>(?&word))
)
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|sub|join|${FUNCNAME}|\%\{))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
|
(?:
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
|
(?:
(?<comp_word_in_listfunc> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&list) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::TRUNK->{is_true})
|
(?:$Regexp::Common::Apache2::TRUNK->{is_false})
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_word> (?&word) )
)
|
(?:
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<join>
\bjoin\(
[[:blank:]\h]*
(?:
(?:
(?<join_list> (?&list) )
[[:blank:]]*\,[[:blank:]]*
(?<join_word> (?&word) )
)
|
(?<join_list> (?&list) )
)
[[:blank:]\h]*
\)
)
(?<list>
(?:
\{
[[:blank:]\h]*
(?<list_words>(?&words_recur))
[[:blank:]\h]*
\}
)
|
(?:
\(
[[:blank:]\h]*
(?<list_parens> (?&list) )
[[:blank:]\h]*
\)
)
|
(?:
(?<list_func>(?&listfunc))
)
|
(?:
(?(?=\bsplit\()
(?<list_split>(?&split))
)
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<regany>
(?:
$Regexp::Common::Apache2::REGEXP->{regex}
|
(?:
(?<regany_regsub> (?®sub) )
)
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<regsub>
s(?<regsep>${REGSEP})
(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regstring>(?>\\\g{regsep}|(?!\g{regsep}).)*+)
\g{regsep}
(?<regflags>${REGFLAGS})?
)
(?<split>
split\(
[[:blank:]\h]*
(?<split_regex>(?®any))
[[:blank:]\h]*\,[[:blank:]\h]*
(?:
(?:
(?<split_word> (?&word) )
)
|
(?:
(?<split_list> (?&list) )
)
)
[[:blank:]\h]*
\)
)
(?<string>
(?:
(?: (?&substring) )
)
|
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<sub>
\bsub\(
[[:blank:]\h]*
(?(?=(?:[s]${REGSEP}))
(?<sub_regsub> (?®sub) )
)
[[:blank:]\h]*
\,
[[:blank:]\h]*
(?<sub_word>
(?<sub_word> (?>(?&word)) )
)
[[:blank:]\h]*
\)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
)
(?<variable>
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
|
(?:
\%\{\:
(?:
(?<var_word> (?&word) )
)
\:\}
)
|
(?:
\%\{\:
(?:
(?<var_cond> (?&cond) )
)
\:\}
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?&word_lax) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
\(
[[:blank:]\h]*
(?<word_parens> (?-2) )
[[:blank:]\h]*
\)
)
|
(?:
(?(?=(?:(?>\\\.|(?!\.).)*+\.(?:.+?)))
(?<word_dot_word>
(?: (?: (?-2)\. )+ (?-2) )
)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?(?=\bsub\b\()
(?<word_sub> (?&sub) )
)
)
|
(?:
(?(?=\bjoin\b\()
(?<word_join> (?&join) )
)
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
(?<word_regex> $Regexp::Common::Apache2::TRUNK->{regex} )
)
)
(?<words_recur>
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?&list) )
)
|
(?:
[[:blank:]\h]*\K
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
[[:blank:]\h]*\K
(?<words_word> (?&word) )
)
)
)
/x;
## Here is the addition to be compliant with expression from 2.3.12 and before,
## ie old fashioned variable such as $REQUEST_URI instead of the modern version %{REQUEST_URI}
@$REGEXP_LEGACY{qw( unary_op digit digits rebackref regpattern regflags regsep regex funcname varname text cstring true false is_true is_false )} =
@$REGEXP{qw( unary_op digit digits rebackref regpattern regflags regsep regex funcname varname text cstring true false is_true is_false )};
## stringcomp
## | integercomp
## | unaryop word
## | word binaryop word
## | word "in" listfunc
## | word "=~" regex
## | word "!~" regex
## | word "in" "{" list "}"
## Ref:
## <http://httpd.apache.org/docs/trunk/en/expr.html#unnop>
## <http://httpd.apache.org/docs/trunk/en/expr.html#binop>
## Here we allow regular expression to be writen like: expression = //, ie without the ~
$REGEXP_LEGACY->{comp} = qr/
(?<comp>
(?:
(?<comp_in_regexp_legacy>
(?<comp_word>(?&word))
[[:blank:]\h]+
(?<comp_regexp_op>[\=\=|\=|\!\=])
[[:blank:]\h]+
(?<comp_regexp>(?®ex))
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_stringcomp>(?&stringcomp))
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_integercomp>(?&integercomp))
)
)
|
(?:
(?<comp_unary>
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<comp_unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_word>(?&word_lax))
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch)))))
(?<comp_binary>
(?<comp_worda>(?&word_lax))
[[:blank:]\h]+
(?:
(?<comp_binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<comp_binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_wordb>(?&word_lax))
)
)
)
|
(?<comp_word_in_listfunc>
(?<comp_word> (?&word_lax) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_listfunc>(?&listfunc))
)
|
(?<comp_in_regexp>
(?<comp_word>(?&word))
[[:blank:]\h]+
(?<comp_regexp_op>[\=|\!]\~)
[[:blank:]\h]+
(?<comp_regexp>$Regexp::Common::Apache2::REGEXP->{regex})
)
|
(?<comp_word_in_list>
(?<comp_word>(?&word))
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_list>(?&words))
[[:blank:]\h]*
\}
)
)
(?(DEFINE)
(?<comp_recur>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch)))))
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
)
|
(?:
(?<comp_word_in_listfunc> (?&word_lax) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?<comp_in_regexp_legacy>
(?=)
(?<comp_word>(?&word))
[[:blank:]\h]+
(?<comp_regexp_op>[\=\=|\=|\!\=])
[[:blank:]\h]+
(?<comp_regexp>(?®ex))
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<cond>
(?:$Regexp::Common::Apache2::REGEXP_LEGACY->{is_true})
|
(?:$Regexp::Common::Apache2::REGEXP_LEGACY->{is_false})
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp_recur))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
(?(<cond_or_expr1>)
(?(<cond_or_expr2>)
(*ACCEPT)
)
)
)
|
(?:
(?<cond_variable>(?&variable))
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
|
(?:
(?: (?&substring) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_rebackref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\$(?<has_accolade>\{)?(?<varname>[a-zA-Z\_]\w*)(?(<has_accolade>)\})
)
|
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<words>
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## "true"
## | "false"
## | "!" cond
## | cond "&&" cond
## | cond "||" cond
## | "(" cond ")"
## | comp
$REGEXP_LEGACY->{cond} = qr/
(?<cond>
(?:
(?<cond_true>$Regexp::Common::Apache2::REGEXP_LEGACY->{is_true})
)
|
(?:
(?<cond_false>$Regexp::Common::Apache2::REGEXP_LEGACY->{is_false})
)
|
(?:
(?:
\(
[[:blank:]\h]*
(?<cond_parenthesis>
(?&cond_recur)
)
[[:blank:]\h]*
\)
)
)
|
(?:
(?<cond_neg>\![[:blank:]\h]*(?<cond_expr>(?&cond_recur)))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and>
(?<cond_and_expr1>
(?: (?&cond_recur) )+
)
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2>
(?: (?&cond_recur) )+
)
)
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or>
(?<cond_or_expr1>
(?: (?&cond_recur) )+
)
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2>
(?: (?&cond_recur) )+
)
)
)
)
|
(?:
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp> (?&comp) )
)
)
|
(?:
(?<cond_variable>(?&variable))
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch)))))
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
)
|
(?:
(?<comp_word_in_listfunc> (?&word_lax) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?<comp_in_regexp_legacy>
(?=)
(?<comp_word>(?&word))
[[:blank:]\h]+
(?<comp_regexp_op>[\=\=|\=|\!\=])
[[:blank:]\h]+
(?<comp_regexp>(?®ex))
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<cond_recur>
(?:$Regexp::Common::Apache2::REGEXP_LEGACY->{is_true})
|
(?:$Regexp::Common::Apache2::REGEXP_LEGACY->{is_false})
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond_recur) )
[[:blank:]\h]*
\)
)
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
(?(<cond_or_expr1>)
(?(<cond_or_expr2>)
(*ACCEPT)
)
)
)
|
(?:
(?<cond_variable>(?&variable))
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<string>
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
|
(?:
(?: (?&substring) )
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_rebackref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\$(?<has_accolade>\{)?(?<varname>[a-zA-Z\_]\w*)(?(<has_accolade>)\})
)
|
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<words>
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/xi;
## cond
## | string
$REGEXP_LEGACY->{expr} = qr/
(?<expr>
(?:
(?<expr_cond>(?&cond))
)
|
(?:
(?<expr_string>(?&string))
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch)))))
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
)
|
(?:
(?<comp_word_in_listfunc> (?&word_lax) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?<comp_in_regexp_legacy>
(?=)
(?<comp_word>(?&word))
[[:blank:]\h]+
(?<comp_regexp_op>[\=\=|\=|\!\=])
[[:blank:]\h]+
(?<comp_regexp>(?®ex))
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::REGEXP_LEGACY->{is_true})
|
(?:$Regexp::Common::Apache2::REGEXP_LEGACY->{is_false})
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
(?(<cond_or_expr1>)
(?(<cond_or_expr2>)
(*ACCEPT)
)
)
)
|
(?:
(?<cond_variable>(?&variable))
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
|
(?:
(?: (?&substring) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_rebackref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\$(?<has_accolade>\{)?(?<varname>[a-zA-Z\_]\w*)(?(<has_accolade>)\})
)
|
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<words>
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## funcname "(" words ")"
## -> Same as LISTFUNC
$REGEXP_LEGACY->{function} = qr/
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch)))))
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
)
|
(?:
(?<comp_word_in_listfunc> (?&word_lax) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?<comp_in_regexp_legacy>
(?=)
(?<comp_word>(?&word))
[[:blank:]\h]+
(?<comp_regexp_op>[\=\=|\=|\!\=])
[[:blank:]\h]+
(?<comp_regexp>(?®ex))
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function_recur>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
|
(?:
(?: (?&substring) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_rebackref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\$(?<has_accolade>\{)?(?<varname>[a-zA-Z\_]\w*)(?(<has_accolade>)\})
)
|
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function_recur) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function_recur) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<words>
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## word "-eq" word | word "eq" word
## | word "-ne" word | word "ne" word
## | word "-lt" word | word "lt" word
## | word "-le" word | word "le" word
## | word "-gt" word | word "gt" word
## | word "-ge" word | word "ge" word
$REGEXP_LEGACY->{integercomp} = qr/
(?<integercomp>
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op>eq|ne|lt|le|gt|ge)
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_integercomp>
(?&integercomp_recur)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch)))))
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
)
|
(?:
(?<comp_word_in_listfunc> (?&word_lax) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?<comp_in_regexp_legacy>
(?=)
(?<comp_word>(?&word))
[[:blank:]\h]+
(?<comp_regexp_op>[\=\=|\=|\!\=])
[[:blank:]\h]+
(?<comp_regexp>(?®ex))
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<integercomp_recur>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
|
(?:
(?: (?&substring) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_rebackref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\$(?<has_accolade>\{)?(?<varname>[a-zA-Z\_]\w*)(?(<has_accolade>)\})
)
|
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<words>
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## listfuncname "(" words ")"
## Use recursion at execution phase for words because it contains dependencies -> list -> listfunc
#(??{$Regexp::Common::Apache2::REGEXP_LEGACY->{words}})
$REGEXP_LEGACY->{listfunc} = qr/
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch)))))
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
)
|
(?:
(?<comp_word_in_listfunc> (?&word_lax) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc_recur) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?<comp_in_regexp_legacy>
(?=)
(?<comp_word>(?&word))
[[:blank:]\h]+
(?<comp_regexp_op>[\=\=|\=|\!\=])
[[:blank:]\h]+
(?<comp_regexp>(?®ex))
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<cond>
(?:$Regexp::Common::Apache2::REGEXP_LEGACY->{is_true})
|
(?:$Regexp::Common::Apache2::REGEXP_LEGACY->{is_false})
|
(?:
\(
[[:blank:]\h]*
(?<cond_parens> (?&cond) )
[[:blank:]\h]*
\)
)
|
(?:
\![[:blank:]\h]*
(?<cond_negative> (?-2) )
)
|
(?(?=(?:(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:(?:\=\=|\!\=|\<|\<\=|\>|\>\=)|(?:\-?(?:eq|ne|lt|le|gt|ge)))[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{)))|(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b)|(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch))))|(?:(?:.*?)[[:blank:]\h]+(?:in|[\=|\!]\~)[[:blank:]\h]+)))
(?<cond_comp>(?&comp))
)
|
(?:
(?(?=(?:.+?)\&\&(?:.+?))
(?<cond_and_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\&\&
[[:blank:]\h]*
(?<cond_and_expr2> (?: (?-2) )+ )
)
)
|
(?:
(?(?=(?:.+?)\|\|(?:.+?))
(?<cond_or_expr1> (?: (?-2) )+ )
[[:blank:]\h]*
\|\|
[[:blank:]\h]*
(?<cond_or_expr2> (?: (?-2) )+ )
)
(?(<cond_or_expr1>)
(?(<cond_or_expr2>)
(*ACCEPT)
)
)
)
|
(?:
(?<cond_variable>(?&variable))
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc_recur>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
|
(?:
(?: (?&substring) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_rebackref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\$(?<has_accolade>\{)?(?<varname>[a-zA-Z\_]\w*)(?(<has_accolade>)\})
)
|
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<words>
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## substring
## | string substring
$REGEXP_LEGACY->{string} = qr/
(?<string>
(?:
(?&substring) # Recurse on the entire substring regexp
)
|
(?:
(?:(?&string_recur)[[:blank:]\h]+(?&substring))
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch)))))
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
)
|
(?:
(?<comp_word_in_listfunc> (?&word_lax) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?<comp_in_regexp_legacy>
(?=)
(?<comp_word>(?&word))
[[:blank:]\h]+
(?<comp_regexp_op>[\=\=|\=|\!\=])
[[:blank:]\h]+
(?<comp_regexp>(?®ex))
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<string_recur>
(?:
(?: (?&substring)[[:blank:]\h]+(?&string_recur) )
)
|
(?:
(?: (?&substring) )
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_rebackref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\$(?<has_accolade>\{)?(?<varname>[a-zA-Z\_]\w*)(?(<has_accolade>)\})
)
|
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string_recur) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<words>
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
)/x;
## word "==" word
## | word "!=" word
## | word "<" word
## | word "<=" word
## | word ">" word
## | word ">=" word
$REGEXP_LEGACY->{stringcomp} = qr/
(?<stringcomp>
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_stringcomp>
(?&stringcomp_recur)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch)))))
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
)
|
(?:
(?<comp_word_in_listfunc> (?&word_lax) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?<comp_in_regexp_legacy>
(?=)
(?<comp_word>(?&word))
[[:blank:]\h]+
(?<comp_regexp_op>[\=\=|\=|\!\=])
[[:blank:]\h]+
(?<comp_regexp>(?®ex))
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
|
(?:
(?: (?&substring) )
)
)
(?<stringcomp_recur>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_rebackref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\$(?<has_accolade>\{)?(?<varname>[a-zA-Z\_]\w*)(?(<has_accolade>)\})
)
|
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<words>
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
$REGEXP_LEGACY->{substring} = qr/
(?<substring>
(?:$Regexp::Common::Apache2::REGEXP_LEGACY->{cstring})
|
(?:
(?&variable)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch)))))
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
)
|
(?:
(?<comp_word_in_listfunc> (?&word_lax) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?<comp_in_regexp_legacy>
(?=)
(?<comp_word>(?&word))
[[:blank:]\h]+
(?<comp_regexp_op>[\=\=|\=|\!\=])
[[:blank:]\h]+
(?<comp_regexp>(?®ex))
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring_recur)[[:blank:]\h]+(?&string) )
)
|
(?:
(?: (?&substring_recur) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring_recur>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_rebackref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\$(?<has_accolade>\{)?(?<varname>[a-zA-Z\_]\w*)(?(<has_accolade>)\})
)
|
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<words>
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## "%{" varname "}"
## | "%{" funcname ":" funcargs "}"
## | "v('" varname "')"
## | "%{:" word ":}"
## | "%{:" cond ":}"
## | rebackref
$REGEXP_LEGACY->{variable} = qr/
(?<variable>
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<varname>[a-zA-Z\_]\w*)(?(<has_accolade>)\})
)
|
(?:
(?:^|\A|(?<!\\))\%\{
(?:
(?<var_func_name>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
(?:^|\A|(?<!\\))\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch)))))
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
)
|
(?:
(?<comp_word_in_listfunc> (?&word_lax) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?<comp_in_regexp_legacy>
(?=)
(?<comp_word>(?&word))
[[:blank:]\h]+
(?<comp_regexp_op>[\=\=|\=|\!\=])
[[:blank:]\h]+
(?<comp_regexp>(?®ex))
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
|
(?:
(?: (?&substring) )
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable_recur) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_rebackref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<variable_recur>
(?:
\$(?<has_accolade>\{)?(?<varname>[a-zA-Z\_]\w*)(?(<has_accolade>)\})
)
|
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable_recur))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable_recur))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<words>
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
## digits
## | "'" string "'"
## | '"' string '"'
## | word "." word
## | variable
## | sub
## | join
## | function
## | "(" word ")"
$REGEXP_LEGACY->{word} = qr/
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits>$Regexp::Common::Apache2::REGEXP_LEGACY->{digits})
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word>
(?: (?&word_recur)\. )+ (?&word_recur)
)
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function>(?&function))
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch)))))
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
)
|
(?:
(?<comp_word_in_listfunc> (?&word_lax) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word_recur) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?<comp_in_regexp_legacy>
(?=)
(?<comp_word>(?&word_recur))
[[:blank:]\h]+
(?<comp_regexp_op>[\=\=|\=|\!\=])
[[:blank:]\h]+
(?<comp_regexp>(?®ex))
)
|
(?:
(?<comp_word_in_list> (?&word_recur) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word_recur))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word_recur))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
|
(?:
(?: (?&substring) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word_recur))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word_recur))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_rebackref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\$(?<has_accolade>\{)?(?<varname>[a-zA-Z\_]\w*)(?(<has_accolade>)\})
)
|
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
)
(?<word_recur>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<words>
(?:
(?<words_word> (?&word_recur) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word_recur) )
)
)
)
/x;
## word
## | word "," list
$REGEXP_LEGACY->{words} = qr/
(?<words>
(?:
(?:
(?<words_list>
(?<words_word>(?&word))
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_sublist>(?&words_recur))
)
)
|
(?:
(?<words_word>(?&word))
)
)
)
(?(DEFINE)
(?<comp>
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*(?:\=\=|\!\=|\<|\<\=|\>|\>\=)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_stringcomp>
(?&stringcomp)
)
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{))(?:.+?)[[:blank:]\h]*\-?(?:eq|ne|lt|le|gt|ge)[[:blank:]\h]*(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))))
(?<comp_integercomp>
(?&integercomp)
)
)
)
|
(?:
(?(?=(?:(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])\b))
(?:(?<=\W)|(?<=^)|(?<=\A))
\-(?<unaryop>[d|e|f|s|L|h|F|U|A|n|z|T|R])
[[:blank:]\h]+
(?<comp_unary_word> (?&word_lax) )
)
)
|
(?:
(?(?=(?:(?:(?:\([[:blank:]\h]*)?(?:[0-9\"\']|${FUNCNAME}\(|\%\{|\$\{?${VARNAME}\}?))(?:.+?)[[:blank:]\h]+(?:(?:\=\=|\=|\!\=|\<|\<\=|\>|\>\=)|(?:(?:(?<comp_binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?:ipmatch|strmatch|strcmatch|fnmatch)))))
(?<comp_binary_worda> (?&word_lax) )
[[:blank:]\h]+
(?:
(?<binaryop>\=\=|\=|\!\=|\<|\<\=|\>|\>\=|(?:\b\-?(?:eq|ne|le|le|gt|ge)\b))
|
(?:
(?:(?<binary_is_neg>\!)[[:blank:]]*)?(?:(?<=\W)|(?<=^)|(?<=\A))\-(?<binaryop>ipmatch|strmatch|strcmatch|fnmatch)
)
)
[[:blank:]\h]+
(?<comp_binary_wordb> (?&word_lax) )
)
)
|
(?:
(?<comp_word_in_listfunc> (?&word_lax) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
(?<comp_word_in_listfunc_func> (?&listfunc) )
)
|
(?:
(?<comp_word_in_regex> (?&word) )
[[:blank:]\h]+
(?<comp_word_in_regex_re> [\=|\!]\~ )
[[:blank:]\h]+
$Regexp::Common::Apache2::REGEXP->{regex}
)
|
(?<comp_in_regexp_legacy>
(?=)
(?<comp_word>(?&word))
[[:blank:]\h]+
(?<comp_regexp_op>[\=\=|\=|\!\=])
[[:blank:]\h]+
(?<comp_regexp>(?®ex))
)
|
(?:
(?<comp_word_in_list> (?&word) )
[[:blank:]\h]+
\-?in
[[:blank:]\h]+
\{
[[:blank:]\h]*
(?<comp_word_list> (?&words) )
[[:blank:]\h]*
\}
)
)
(?<function>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<integercomp>
(?:
(?<integercomp_worda>(?&word))
[[:blank:]\h]+
\-?(?<integercomp_op> (?:eq|ne|lt|le|gt|ge) )
[[:blank:]\h]+
(?<integercomp_wordb>(?&word))
)
)
(?<listfunc>
(?:
(?!\bv\()(?<func_name>[a-zA-Z]\w*)
\(
[[:blank:]\h]*
(?<func_args>
(?> (?&func_words) )?
)
[[:blank:]\h]*
\)
)
|
(?:
( # paren group 1 (full function)
(?!\bv\() # Take care to avoid catching modern-style variable v()
(?<func_name>[a-zA-Z_]\w*) # possible a function with its name, or just parenthesis
(?<paren_group> # paren group 2 (parens)
\(
(?<func_args> # paren group 3 (contents of parens)
(?:
(?> (?:\\[()]|(?![()]).)+ ) # escaped parens or no parens
|
(?&paren_group) # Recurse to named capture group
)*
)
\)
)
)
)
)
(?<func_words>
(?:
(?<words_list_word>
(?:
(?&word)
[[:blank:]\h]*\,[[:blank:]\h]*
)*
(?&word)
)
(?:
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_word> (?&word) )
)?
)
|
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
(?<regex>
(?:(?<regsep>\/)(?<regpattern>(?>\\[[:cntrl:]\/]|[^[:cntrl:]\/])*+)\/(?<regflags>[i|s|m|g]+)?)
|
(?:m(?<regsep>[\/\#\$\%\^\|\?\!\'\"\,\;\:\.\_\-])(?<regpattern>(?>\\\g{regsep}|(?!\g{regsep}).)*+)\g{regsep}(?<regflags>[i|s|m|g]+)?)
)
(?<string>
(?:
(?: (?&substring)[[:blank:]\h]+(?&string) )
)
|
(?:
(?: (?&substring) )
)
)
(?<stringcomp>
(?:
(?<stringcomp_worda>(?&word))
[[:blank:]\h]+
(?<stringcomp_op>\=\=|\=|\!\=|\<|\<\=|\>|\>\=)
[[:blank:]\h]+
(?<stringcomp_wordb>(?&word))
)
)
(?<substring>
(?:
(?<substring_cstring>$Regexp::Common::Apache2::REGEXP->{cstring})
)
|
(?:
(?<sub_var> (?&variable) )
)
|
(?:
\$(?<has_accolade>\{)?(?<sub_rebackref>${DIGIT})(?(<has_accolade>)\})
)
)
(?<variable>
(?:
\$(?<has_accolade>\{)?(?<varname>[a-zA-Z\_]\w*)(?(<has_accolade>)\})
)
|
(?:
\%\{
(?:
(?<var_func>${FUNCNAME})\:(?<var_func_args>(?>\\\}|[^\}])*+)
)
\}
)
|
(?:
\%\{
(?:
(?<varname>${VARNAME})
)
\}
)
|
(?:
\bv\(
[[:blank:]\h]*
(?<var_quote>["'])
(?:
(?<varname>${VARNAME})
)
[[:blank:]\h]*
\g{var_quote}
\)
)
|
(?:
(?:^|\A|(?<!\\))
(?<var_backref>
\$(?<has_accolade>\{)?
(?<rebackref>${DIGIT})
(?(<has_accolade>)\})
)
)
)
(?<word>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<word_lax>
(?:
(?<word_ip>
(?<word_ip4>$IPv4)
|
(?<word_ip6>$IPv6)
)
)
|
(?:
(?<word_digits> $Regexp::Common::Apache2::REGEXP_LEGACY->{digits} )
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?>\\\g{word_quote}|(?!\g{word_quote}).)*+ )
)
\g{word_quote}
)
|
(?:
(?<word_quote>['"])
(?:
(?<word_enclosed> (?&string) )
)
\g{word_quote}
)
|
(?:
(?<word_dot_word> (?: (?-2)\. )+ (?-2) )
)
|
(?:
(?:^|\A|(?<!\\))\$(?<has_accolade>\{)?(?<word_rebackref>${DIGIT})(?(<has_accolade>)\})
)
|
(?:
(?<word_variable>(?&variable))
)
|
(?:
(?<word_function> (?&function) )
)
|
(?:
$Regexp::Common::Apache2::REGEXP_LEGACY->{regex}
)
)
(?<words_recur>
(?:
(?<words_word> (?&word) )
[[:blank:]\h]*\,[[:blank:]\h]*
(?<words_list> (?-2) )
)
|
(?:
(?<words_word> (?&word) )
)
)
)
/x;
pattern name => [qw( Apache2 -legacy=1 -trunk=1 ) ],
create => sub
{
my( $self, $flags ) = @_;
my %re = %$REGEXP;
## Override vanilla regular expressions by the extended ones
if( $flags->{'-legacy'} )
{
my @k = keys( %$REGEXP_LEGACY );
@re{ @k } = @$REGEXP_LEGACY{ @k };
}
elsif( $flags->{'-trunk'} )
{
my @k = keys( %$TRUNK );
@re{ @k } = @$TRUNK{ @k };
}
my $pat = join( '|' => values( %re ) );
return( "(?k:$pat)" );
};
pattern name => [qw( Apache2 Comp )],
create => $REGEXP->{comp};
pattern name => [qw( Apache2 Cond )],
create => $REGEXP->{cond};
pattern name => [qw( Apache2 Digits )],
create => $REGEXP->{digits};
pattern name => [qw( Apache2 Expression )],
create => $REGEXP->{expr};
pattern name => [qw( Apache2 Function )],
create => $REGEXP->{function};
pattern name => [qw( Apache2 IntegerComp )],
create => $REGEXP->{integercomp};
pattern name => [qw( Apache2 ListFunc )],
create => $REGEXP->{listfunc};
pattern name => [qw( Apache2 Regexp )],
create => $REGEXP->{regex};
pattern name => [qw( Apache2 String )],
create => $REGEXP->{string};
pattern name => [qw( Apache2 StringComp )],
create => $REGEXP->{stringcomp};
pattern name => [qw( Apache2 Substring )],
create => $REGEXP->{substring};
pattern name => [qw( Apache2 Variable )],
create => $REGEXP->{variable};
pattern name => [qw( Apache2 Word )],
create => $REGEXP->{word};
pattern name => [qw( Apache2 Words )],
create => $REGEXP->{words};
## Apache2 Trunk expressions
pattern name => [qw( Apache2 TrunkComp )],
create => $TRUNK->{comp};
pattern name => [qw( Apache2 TrunkCond )],
create => $TRUNK->{cond};
pattern name => [qw( Apache2 TrunkDigits )],
create => $TRUNK->{digits};
pattern name => [qw( Apache2 TrunkExpression )],
create => $TRUNK->{expr};
pattern name => [qw( Apache2 TrunkFunction )],
create => $TRUNK->{function};
pattern name => [qw( Apache2 TrunkIntegerComp )],
create => $TRUNK->{integercomp};
pattern name => [qw( Apache2 TrunkJoin )],
create => $TRUNK->{join};
pattern name => [qw( Apache2 TrunkList )],
create => $TRUNK->{list};
pattern name => [qw( Apache2 TrunkListFunc )],
create => $TRUNK->{listfunc};
pattern name => [qw( Apache2 TrunkRegany )],
create => $TRUNK->{regany};
pattern name => [qw( Apache2 TrunkRegexp )],
create => $TRUNK->{regex};
pattern name => [qw( Apache2 TrunkRegsub )],
create => $TRUNK->{regsub};
pattern name => [qw( Apache2 TrunkSplit )],
create => $TRUNK->{split};
pattern name => [qw( Apache2 TrunkString )],
create => $TRUNK->{string};
pattern name => [qw( Apache2 TrunkStringComp )],
create => $TRUNK->{stringcomp};
pattern name => [qw( Apache2 TrunkSub )],
create => $TRUNK->{sub};
pattern name => [qw( Apache2 TrunkSubstring )],
create => $TRUNK->{substring};
pattern name => [qw( Apache2 TrunkVariable )],
create => $TRUNK->{variable};
pattern name => [qw( Apache2 TrunkWord )],
create => $TRUNK->{word};
pattern name => [qw( Apache2 TrunkWords )],
create => $TRUNK->{words};
## Legacy expressions
pattern name => [qw( Apache2 LegacyComp )],
create => $REGEXP_LEGACY->{comp};
pattern name => [qw( Apache2 LegacyCond )],
create => $REGEXP_LEGACY->{cond};
pattern name => [qw( Apache2 LegacyDigits )],
create => $REGEXP_LEGACY->{digits};
pattern name => [qw( Apache2 LegacyExpression )],
create => $REGEXP_LEGACY->{expr};
pattern name => [qw( Apache2 LegacyFunction )],
create => $REGEXP_LEGACY->{function};
pattern name => [qw( Apache2 LegacyIntegerComp )],
create => $REGEXP_LEGACY->{integercomp};
pattern name => [qw( Apache2 LegacyListFunc )],
create => $REGEXP_LEGACY->{listfunc};
pattern name => [qw( Apache2 LegacyRegexp )],
create => $REGEXP_LEGACY->{regex};
pattern name => [qw( Apache2 LegacyString )],
create => $REGEXP_LEGACY->{string};
pattern name => [qw( Apache2 LegacyStringComp )],
create => $REGEXP_LEGACY->{stringcomp};
pattern name => [qw( Apache2 LegacySubstring )],
create => $REGEXP_LEGACY->{substring};
pattern name => [qw( Apache2 LegacyVariable )],
create => $REGEXP_LEGACY->{variable};
pattern name => [qw( Apache2 LegacyWord )],
create => $REGEXP_LEGACY->{word};
pattern name => [qw( Apache2 LegacyWords )],
create => $REGEXP_LEGACY->{words};
};
{
package
Regexp::Common::Apache2::Boolean;
BEGIN
{
use strict;
use warnings;
use overload
"0+" => sub{ ${$_[0]} },
"++" => sub{ $_[0] = ${$_[0]} + 1 },
"--" => sub{ $_[0] = ${$_[0]} - 1 },
fallback => 1;
our( $VERSION ) = '0.1.0';
};
sub new { return( $_[1] ? $true : $false ); }
sub defined { return( 1 ); }
our $true = do{ bless( \( my $dummy = 1 ) => Regexp::Common::Apache2::Boolean ) };
our $false = do{ bless( \( my $dummy = 0 ) => Regexp::Common::Apache2::Boolean ) };
sub true () { $true }
sub false () { $false }
sub is_bool ($) { UNIVERSAL::isa( $_[0], Regexp::Common::Apache2::Boolean ) }
sub is_true ($) { $_[0] && UNIVERSAL::isa( $_[0], Regexp::Common::Apache2::Boolean ) }
sub is_false ($) { !$_[0] && UNIVERSAL::isa( $_[0], Regexp::Common::Apache2::Boolean ) }
sub TO_JSON
{
## JSON does not check that the value is a proper true or false. It stupidly assumes this is a string
## The only way to make it understand is to return a scalar ref of 1 or 0
# return( $_[0] ? 'true' : 'false' );
return( $_[0] ? \1 : \0 );
}
}
1;
__END__
=encoding utf-8
=pod
=head1 NAME
Regexp::Common::Apache2 - Apache2 Expressions
=head1 SYNOPSIS
use Regexp::Common qw( Apache2 );
use Regexp::Common::Apache2 qw( $ap_true $ap_false );
while( <> )
{
my $pos = pos( $_ );
/\G$RE{Apache2}{Word}/gmc and print "Found a word expression at pos $pos\n";
/\G$RE{Apache2}{Variable}/gmc and print "Found a variable $+{varname} at pos $pos\n";
}
# Override Apache2 expressions by the legacy ones
$RE{Apache2}{-legacy => 1}
# or use it with the Legacy prefix:
if( $str =~ /^$RE{Apache2}{LegacyVariable}$/ )
{
print( "Found variable $+{variable} with name $+{varname}\n" );
}
=head1 VERSION
v0.2.1
=head1 DESCRIPTION
This is the perl port of L<Apache2 expressions|https://httpd.apache.org/docs/trunk/en/expr.html>
The regular expressions have been designed based on Apache2 Backus-Naur Form (BNF) definition as described below in L</"APACHE2 EXPRESSION">
You can also use the extended pattern by calling L<Regexp::Common::Apache2> like:
$RE{Apache2}{-legacy => 1}
All of the regular expressions use named capture. See L<perlvar/%+> for more information on named capture.
=head1 APACHE2 EXPRESSION
=head2 comp
BNF:
stringcomp
| integercomp
| unaryop word
| word binaryop word
| word "in" listfunc
| word "=~" regex
| word "!~" regex
| word "in" "{" words "}"
$RE{Apache2}{Comp}
For example:
"Jack" != "John"
123 -ne 456
# etc
This uses other expressions namely L</stringcomp>, L</integercomp>, L</word>, L</listfunc>, L</regex>, L</words>
The capture names are:
=over 4
=item I<comp>
Contains the entire capture block
=item I<comp_binary>
Matches the expression that uses a binary operator, such as:
==, =, !=, <, <=, >, >=, -ipmatch, -strmatch, -strcmatch, -fnmatch
=item I<comp_binaryop>
The binary op used if the expression is a binary comparison. Binary operator is:
==, =, !=, <, <=, >, >=, -ipmatch, -strmatch, -strcmatch, -fnmatch
=item I<comp_integercomp>
When the comparison is for an integer comparison as opposed to a string comparison.
=item I<comp_list>
Contains the list used to check a word against, such as:
"Jack" in {"John", "Peter", "Jack"}
=item I<comp_listfunc>
This contains the I<listfunc> when the expressions contains a word checked against a list function, such as:
"Jack" in listMe("some arguments")
=item I<comp_regexp>
The regular expression used when a word is compared to a regular expression, such as:
"Jack" =~ /\w+/
Here, I<comp_regexp> would contain C</\w+/>
=item I<comp_regexp_op>
The regular expression operator used when a word is compared to a regular expression, such as:
"Jack" =~ /\w+/
Here, I<comp_regexp_op> would contain C<=~>
=item I<comp_stringcomp>
When the comparison is for a string comparison as opposed to an integer comparison.
=item I<comp_unary>
Matches the expression that uses unary operator, such as:
-d, -e, -f, -s, -L, -h, -F, -U, -A, -n, -z, -T, -R
For example:
-A /some/uri.html # (same as -U)
-d /some/folder # file is a directory
-e /some/folder/file.txt # file exists
-f /some/folder/file.txt # file is a regular file
-F /some/folder/file.txt # file is a regular file and is accessible to all (Apache2 does a sub query to check)
-h /some/folder/link.txt # true if file is a symbolic link
-n %{QUERY_STRING} # true if string is not empty (opposite of -z)
-s /some/folder/file.txt # true if file is not empty
-L /some/folder/link.txt # true if file is a symbolic link (same as -h)
-R 192.168.1.1/24 # remote ip match this ip block; same as %{REMOTE_ADDR} -ipmatch 192.168.1.1/24
-T %{HTTPS} # false if string is empty, "0", "off", "false", or "no" (case insensitive). True otherwise.
-U /some/uri.html # check if the uri is accessible to all (Apache2 does a sub query to check)
-z %{QUERY_STRING} # true if string is empty (opposite of -n)
=item I<comp_word>
Contains the word that is the object of the comparison.
=item I<comp_word_in_list>
Contains the expression of a word checked against a list, such as:
"Jack" in {"John", "Peter", "Jack"}
=item I<comp_word_in_listfunc>
Contains the word when it is being compared to a L<listfunc>, such as:
"Jack" in listMe("some arguments")
=item I<comp_word_in_regexp>
Contains the expression of a word checked against a regular expression, such as:
"Jack" =~ /\w+/
Here the word C<Jack> (without the parenthesis) would be captured in I<comp_word>
=item I<comp_worda>
Contains the first word in comparison expression
=item I<comp_wordb>
Contains the second word in comparison expression
=back
=head2 cond
BNF:
"true"
| "false"
| "!" cond
| cond "&&" cond
| cond "||" cond
| comp
| "(" cond ")"
$RE{Apache2}{Cond}
For example:
use Regexp::Common::Apache qw( $ap_true $ap_false );
($ap_false && $ap_true)
The capture names are:
=over 4
=item I<cond>
Contains the entire capture block
=item I<cond_and>
Contains the expression like:
($ap_true && $ap_true)
=item I<cond_and_expr1>
The first expression in a ANDed condition, such as :
$ap_true && $ap_false
=item I<cond_and_expr2>
The second expression in a ANDed condition, such as :
$ap_true && $ap_false
=item I<cond_comp>
Contains the comparison expression. See L</comp> above.
=item I<cond_expr>
Expression that is capture after following a negatiion, such as :
!-e /some/folder/file.txt
Here I<cond_expr> would contain C<-e /some/folder/file.txt>
=item I<cond_false>
Contains the false expression like:
($ap_false)
false # as a litteral word
0 # 0 as a standalone number not surrounded by any number or letter
=item I<cond_neg>
Contains the expression if it is preceded by an exclamation mark, such as:
!$ap_true
=item I<cond_or>
Contains the expression like:
($ap_true || $ap_true)
=item I<cond_or_expr1>
The first expression in a ORed condition, such as :
$ap_true && $ap_false
=item I<cond_or_expr2>
The second expression in a ORed condition, such as :
$ap_true && $ap_false
=item I<cond_parenthesis>
Contains the condition when it is embedded within parenthesis.
=item I<cond_true>
Contains the true expression like:
($ap_true)
true # as a litteral word
1 # 1 as a standalone number not surrounded by any number or letter
=back
=head2 expr
BNF: cond | string
$RE{Apache2}{Expr}
The capture names are:
=over 4
=item I<expr>
Contains the entire capture block
=item I<expr_cond>
Contains the expression of the condition
=item I<expr_string>
Contains the expression of a string
=back
=head2 function
BNF: funcname "(" words ")"
$RE{Apache2}{Function}
For example:
base64("Some string")
someFunc()
md5( "one arg" )
otherFunc( %{some_var}, "quoted", split( /\w+/, "John Paul" ) )
The capture names are:
=over 4
=item I<function>
Contains the entire capture block
=item I<func_args>
Contains the list of arguments. In the example above, this would be C<Some string>
=item I<func_name>
The name of the function . In the example above, this would be C<base64>
=back
=head2 integercomp
BNF:
word "-eq" word | word "eq" word
| word "-ne" word | word "ne" word
| word "-lt" word | word "lt" word
| word "-le" word | word "le" word
| word "-gt" word | word "gt" word
| word "-ge" word | word "ge" word
$RE{Apache2}{IntegerComp}
For example:
123 -ne 456
789 gt 234
# etc
The hyphen before the operator is optional, so you can say C<eq> instead of C<-eq>
The capture names are:
=over 4
=item I<stringcomp>
Contains the entire capture block
=item I<integercomp_op>
Contains the comparison operator
=item I<integercomp_worda>
Contains the first word in the string comparison
=item I<integercomp_wordb>
Contains the second word in the string comparison
=back
=head2 listfunc
BNF: listfuncname "(" words ")"
$RE{Apache2}{ListFunc}
For example:
base64("Some string")
someFunc()
md5( "one arg" )
otherFunc( %{some_var}, "quoted", split( /\w+/, "John Paul" ) )
This is quite similar to the L</function> regular expression
The capture names are:
=over 4
=item I<listfunc>
Contains the entire capture block
=item I<func_args>
Contains the list of arguments. In the example above, this would be C<Some string>
=item I<func_name>
The name of the function . In the example above, this would be C<base64>
=back
=head2 regex
BNF:
"/" regpattern "/" [regflags]
| "m" regsep regpattern regsep [regflags]
$RE{Apache2}{Regexp}
For example:
/\w+/i
# or
m,\w+,i
The capture names are:
=over 4
=item I<regex>
Contains the entire capture block
=item I<regflags>
The regular expression modifiers. See L<perlre>
This can be any combination of:
i, s, m, g
=item I<regpattern>
Contains the regular expression. See L<perlre> for example and explanation of how to use regular expression. Apache2 uses PCRE, i.e. perl compliant regular expressions.
=item I<regsep>
Contains the regular expression separator, which can be any of:
/, #, $, %, ^, |, ?, !, ', ", ",", ;, :, ".", _, -
=back
=head2 string
BNF: substring | string substring
$RE{Apache2}{String}
For example:
URI accessed is: %{REQUEST_URI}
The capture names are:
=over 4
=item I<string>
Contains the entire capture block
=back
=head2 stringcomp
BNF:
word "==" word
| word "!=" word
| word "<" word
| word "<=" word
| word ">" word
| word ">=" word
$RE{Apache2}{StringComp}
For example:
"John" == "Jack"
sub(s/\w+/Jack/i, "John") != "Jack"
# etc
The capture names are:
=over 4
=item I<stringcomp>
Contains the entire capture block
=item I<stringcomp_op>
Contains the comparison operator
=item I<stringcomp_worda>
Contains the first word in the string comparison
=item I<stringcomp_wordb>
Contains the second word in the string comparison
=back
=head2 substring
BNF: cstring | variable | rebackref
$RE{Apache2}{Substring}
For example:
Jack
# or
%{REQUEST_URI}
See L</variable> and L</word> regular expression for more on those.
The capture names are:
=over 4
=item I<rebackref>
Contains a regular expression back reference such as C<$1>, C<$2>, etc up to C<$9>
=item I<substring>
Contains the entire capture block
=back
=head2 variable
BNF:
"%{" varname "}"
| "%{" funcname ":" funcargs "}"
| "v(" varname ")"
$RE{Apache2}{Variable}
# or to enable legacy variable:
$RE{Apache2}{LegacyVariable}
For example:
%{REQUEST_URI}
# or
%{md5:"some string"}
# or
v(REQUEST_URI)
# legacy variable allows extended variable. See LEGACY APACHE2 EXPRESSION below
See L</word> and L</cond> regular expression for more on those.
The capture names are:
=over 4
=item I<variable>
Contains the entire capture block
=item I<var_func>
Contains the text for the function and its arguments if this is a function.
=item I<var_func_args>
Contains the function arguments.
=item I<var_func_name>
Contains the function name.
=item I<varname>
Contains the variable name without the percent sign or dollar sign (if legacy regular expression is enabled) or the possible surrounding accolades
=back
=head2 word
BNF:
digits
| "'" string "'"
| '"' string '"'
| word "." word
| variable
| function
| "(" word ")"
| rebackref
$RE{Apache2}{Word}
This is the most complex regular expression used, since it uses all the others and can recurse deeply
For example:
12
# or
"John"
# or
'Jack'
# or
%{REQUEST_URI}
# or
%{HTTP_HOST}.%{HTTP_PORT}
# or
md5("some string")
# or any word surrounded by parenthesis, such as:
("John")
See L</string>, L</word>, L</variable>, L</function> regular expression for more on those.
The capture names are:
=over 4
=item I<rebackref>
Contains a regular expression back reference such as C<$1>, C<$2>, etc up to C<$9>
=item I<word>
Contains the entire capture block
=item I<word_digits>
If the word is actually digits, ths contains those digits.
=item I<word_dot_word>
This contains the text when two words are separated by a dot.
=item I<word_enclosed>
Contains the value of the word enclosed by single or double quotes or by surrounding parenthesis.
=item I<word_function>
Contains the word containing a L</function>
=item I<word_quote>
If the word is enclosed by single or double quote, this contains the single or double quote character
=item I<word_variable>
Contains the word containing a L</variable>
=back
=head2 words
BNF:
word
| word "," word
$RE{Apache2}{Words}
For example:
"Jack"
# or
"John", "Peter", "Paul"
See L</word> and L</list> regular expression for more on those.
The capture names are:
=over 4
=item I<words>
Contains the entire capture block
=item I<words_word>
Contains the word
=item I<words_list>
Contains the list
=back
=head1 ADVANCED APACHE2 EXPRESSION
=head2 comp
BNF:
stringcomp
| integercomp
| unaryop word
| word binaryop word
| word "in" listfunc
| word "=~" regex
| word "!~" regex
| word "in" "{" list "}"
$RE{Apache2}{TrunkComp}
For example:
"Jack" != "John"
123 -ne 456
# etc
This uses other expressions namely L</stringcomp>, L</integercomp>, L</word>, L</listfunc>, L</regex>, L</list>
This is similar to the regular L</comp> in L</"APACHE2 EXPRESSION">, except it uses L</list> instead of L</words>
The capture names are:
=over 4
=item I<comp>
Contains the entire capture block
=item I<comp_binary>
Matches the expression that uses a binary operator, such as:
==, =, !=, <, <=, >, >=, -ipmatch, -strmatch, -strcmatch, -fnmatch
=item I<comp_binaryop>
The binary op used if the expression is a binary comparison. Binary operator is:
==, =, !=, <, <=, >, >=, -ipmatch, -strmatch, -strcmatch, -fnmatch
=item I<comp_integercomp>
When the comparison is for an integer comparison as opposed to a string comparison.
=item I<comp_list>
Contains the list used to check a word against, such as:
"Jack" in {"John", "Peter", "Jack"}
=item I<comp_listfunc>
This contains the I<listfunc> when the expressions contains a word checked against a list function, such as:
"Jack" in listMe("some arguments")
=item I<comp_regexp>
The regular expression used when a word is compared to a regular expression, such as:
"Jack" =~ /\w+/
Here, I<comp_regexp> would contain C</\w+/>
=item I<comp_regexp_op>
The regular expression operator used when a word is compared to a regular expression, such as:
"Jack" =~ /\w+/
Here, I<comp_regexp_op> would contain C<=~>
=item I<comp_stringcomp>
When the comparison is for a string comparison as opposed to an integer comparison.
=item I<comp_unary>
Matches the expression that uses unary operator, such as:
-d, -e, -f, -s, -L, -h, -F, -U, -A, -n, -z, -T, -R
=item I<comp_word>
Contains the word that is the object of the comparison.
=item I<comp_word_in_list>
Contains the expression of a word checked against a list, such as:
"Jack" in {"John", "Peter", "Jack"}
=item I<comp_word_in_listfunc>
Contains the word when it is being compared to a L<listfunc>, such as:
"Jack" in listMe("some arguments")
=item I<comp_word_in_regexp>
Contains the expression of a word checked against a regular expression, such as:
"Jack" =~ /\w+/
Here the word C<Jack> (without the parenthesis) would be captured in I<comp_word>
=item I<comp_worda>
Contains the first word in comparison expression
=item I<comp_wordb>
Contains the second word in comparison expression
=back
=head2 cond
BNF:
"true"
| "false"
| "!" cond
| cond "&&" cond
| cond "||" cond
| comp
| "(" cond ")"
$RE{Apache2}{TrunkCond}
Same as L</cond> in L</"APACHE2 EXPRESSION">
=head2 expr
BNF: cond | string
$RE{Apache2}{TrunkExpr}
Same as L</cond> in L</"APACHE2 EXPRESSION">
=head2 function
BNF: funcname "(" words ")"
$RE{Apache2}{TrunkFunction}
Same as L</cond> in L</"APACHE2 EXPRESSION">
=head2 integercomp
BNF:
word "-eq" word | word "eq" word
| word "-ne" word | word "ne" word
| word "-lt" word | word "lt" word
| word "-le" word | word "le" word
| word "-gt" word | word "gt" word
| word "-ge" word | word "ge" word
$RE{Apache2}{TrunkIntegerComp}
Same as L</cond> in L</"APACHE2 EXPRESSION">
=head2 join
BNF:
"join" ["("] list [")"]
| "join" ["("] list "," word [")"]
$RE{Apache2}{TrunkJoin}
For example:
join({"word1" "word2"})
# or
join({"word1" "word2"}, ', ')
This uses L</list> and L</word>
The capture names are:
=over 4
=item I<join>
Contains the entire capture block
=item I<join_list>
Contains the value of the list
=item I<join_word>
Contains the value for word used to join the list
=back
=head2 list
BNF:
split
| listfunc
| "{" words "}"
| "(" list ")
$RE{Apache2}{TrunkList}
For example:
split( /\w+/, "Some string" )
# or
{"some", "words"}
# or
(split( /\w+/, "Some string" ))
# or
( {"some", "words"} )
This uses L</split>, L</listfunc>, L<words> and L</list>
The capture names are:
=over 4
=item I<list>
Contains the entire capture block
=item I<list_func>
Contains the value if a L</listfunc> is used
=item I<list_list>
Contains the value if this is a list embedded within parenthesis
=item I<list_split>
Contains the value if the list is based on a L<split>
=item I<list_words>
Contains the value for a list of words.
=back
=head2 listfunc
BNF: listfuncname "(" words ")"
$RE{Apache2}{TrunkListFunc}
Same as L</cond> in L</"APACHE2 EXPRESSION">
=head2 regany
BNF: regex | regsub
$RE{Apache2}{TrunkRegany}
For example:
/\w+/i
# or
m,\w+,i
This regular expression includes L</regany> and L</regsub>
The capture names are:
=over 4
=item I<regany>
Contains the entire capture block
=item I<regany_regex>
Contains the regular expression. See L</regex>
=item I<regany_regsub>
Contains the substitution regular expression. See L</regsub>
=back
=head2 regex
BNF:
"/" regpattern "/" [regflags]
| "m" regsep regpattern regsep [regflags]
$RE{Apache2}{TrunkRegexp}
Same as L</cond> in L</"APACHE2 EXPRESSION">
=head2 regsub
BNF: "s" regsep regpattern regsep string regsep [regflags]
$RE{Apache2}{TrunkRegsub}
For example:
s/\w+/John/gi
The capture names are:
=over 4
=item I<regflags>
The modifiers used which can be any combination of:
i, s, m, g
See L<perlre> for an explanation of their usage and meaning
=item I<regstring>
The string replacing the text found by the regular expression
=item I<regsub>
Contains the entire capture block
=item I<regpattern>
Contains the regular expression which is perl compliant since Apache2 uses PCRE.
=item I<regsep>
Contains the regular expression separator, which can be any of:
/, #, $, %, ^, |, ?, !, ', ", ",", ;, :, ".", _, -
=back
=head2 split
BNF:
"split" ["("] regany "," list [")"]
| "split" ["("] regany "," word [")"]
$RE{Apache2}{TrunkSplit}
For example:
split( /\w+/, "Some string" )
This uses L</regany>, L</list> and L</word>
The capture names are:
=over 4
=item I<split>
Contains the entire capture block
=item I<split_regex>
Contains the regular expression used for the split
=item I<split_list>
The list being split. It can also be a word. See below
=item I<split_word>
The word being split. It can also be a list. See above
=back
=head2 string
BNF: substring | string substring
$RE{Apache2}{TrunkString}
Same as L</cond> in L</"APACHE2 EXPRESSION">
=head2 stringcomp
BNF:
word "==" word
| word "!=" word
| word "<" word
| word "<=" word
| word ">" word
| word ">=" word
$RE{Apache2}{TrunkStringComp}
Same as L</cond> in L</"APACHE2 EXPRESSION">
=head2 sub
BNF: "sub" ["("] regsub "," word [")"]
$RE{Apache2}{TrunkSub}
For example:
sub(s/\w/John/gi,"Peter")
The capture names are:
=over 4
=item I<sub>
Contains the entire capture block
=item I<sub_regsub>
Contains the substitution expression, i.e. in the example above, this would be:
s/\w/John/gi
=item I<sub_word>
The target for the substitution. In the example above, this would be "Peter"
=back
=head2 substring
BNF: cstring | variable
$RE{Apache2}{TrunkSubstring}
For example:
Jack
# or
%{REQUEST_URI}
# or
%{:sub(s/\b\w+\b/Peter/, "John"):}
See L</variable> and L</word> regular expression for more on those.
This is different from L</substring> in L</"APACHE2 EXPRESSION"> in that it does not include regular expression back reference, i.e. C<$1>, C<$2>, etc.
The capture names are:
=over 4
=item I<substring>
Contains the entire capture block
=back
=head2 variable
BNF:
"%{" varname "}"
| "%{" funcname ":" funcargs "}"
| "v('" varname "')"
| "%{:" word ":}"
| "%{:" cond ":}"
| rebackref
$RE{Apache2}{TrunkVariable}
For example:
%{REQUEST_URI}
# or
%{md5:"some string"}
# or
%{:sub(s/\b\w+\b/Peter/, "John"):}
# or a reference to previous regular expression capture groups
$1, $2, etc..
See L</word> and L</cond> regular expression for more on those.
The capture names are:
=over 4
=item I<rebackref>
Contains the regular expression back reference such as C<$1>, C<$2>, etc
But without the leading dollar sign nor the enclosing accolade, if any, thus in the example of C<$1> or C<${1}> I<rebackref> would be C<1>
=item I<variable>
Contains the entire capture block
=item I<var_backref>
Contains the regular expression back reference such as C<$1>, C<$2>, etc
This includes the leadaing dollar sign and any enclosing accolade, if any, such as C<${1}>
=item I<var_cond>
If this is a condition inside a variable, such as:
%{:$ap_true == $ap_false}
=item I<var_func>
Contains the text for the function and its arguments if this is a function.
=item I<var_func_args>
Contains the function arguments.
=item I<var_func_name>
Contains the function name.
=item I<var_word>
A variable containing a word. See L</word> for more information about word expressions.
=item I<varname>
Contains the variable name without the percent sign or dollar sign (if legacy regular expression is enabled) or the possible surrounding accolades
=back
=head2 word
BNF:
digits
| "'" string "'"
| '"' string '"'
| word "." word
| variable
| sub
| join
| function
| "(" word ")"
$RE{Apache2}{TrunkWord}
This is the most complex regular expression used, since it uses all the others and can recurse deeply
For example:
12
# or
"John"
# or
'Jack'
# or
%{REQUEST_URI}
# or
%{HTTP_HOST}.%{HTTP_PORT}
# or
%{:sub(s/\b\w+\b/Peter/, "John"):}
# or
sub(s,\w+,Paul,gi, "John")
# or
join({"Paul", "Peter"}, ', ')
# or
md5("some string")
# or any word surrounded by parenthesis, such as:
("John")
See L</string>, L</word>, L</variable>, L</sub>, L</join>, L</function> regular expression for more on those.
The capture names are:
=over 4
=item I<word>
Contains the entire capture block
=item I<word_digits>
If the word is actually digits, thise contains those digits.
=item I<word_dot_word>
This contains the text when two words are separated by a dot.
=item I<word_enclosed>
Contains the value of the word enclosed by single or double quotes or by surrounding parenthesis.
=item I<word_function>
Contains the word containing a L</function>
=item I<word_join>
Contains the word containing a L</join>
=item I<word_quote>
If the word is enclosed by single or double quote, this contains the single or double quote character
=item I<word_sub>
If the word is a substitution, this contains tha substitution
=item I<word_variable>
Contains the word containing a L</variable>
=back
=head2 words
BNF:
word
| word "," list
$RE{Apache2}{TrunkWords}
For example:
"Jack"
# or
"John", {"Peter", "Paul"}
# or
sub(s/\b\w+\b/Peter/, "John"), {"Peter", "Paul"}
See L</word> and L</list> regular expression for more on those.
It is different from L</words> in L</"APACHE2 EXPRESSION"> in that it uses L</list> instead of L</word>
The capture names are:
=over 4
=item I<words>
Contains the entire capture block
=item I<words_word>
Contains the word
=item I<words_list>
Contains the list
=back
=head1 LEGACY
When using legacy mode, the regular expressions are more laxed in what they accept around 3 types of expressions:
=over
=item 1. I<comp>
Same as L</comp>, and it extends it by adding support for legacy regular expression, i.e. without using the tilde (C<~>). For example :
$HTTP_COOKIES = /lang\%22\%3A\%22([a-zA-Z]+\-[a-zA-Z]+)\%22\%7D;?/
In current version of Apache2 expression this would rather be writen as:
%{HTTP_COOKIES} =~ /lang\%22\%3A\%22([a-zA-Z]+\-[a-zA-Z]+)\%22\%7D;?/
Both are supported in legacy expressions.
The additional capture groups available are:
=over 4
=item I<comp_in_regexp_legacy>
Contains the entire legacy regular expression.
=item I<comp_regexp> (unchanged)
Contains the regular expression.
=item I<comp_regexp_op>
Contains the operator, which may be C<=>, or C<==>, or C<!=>
=item I<comp_word> (unchanged)
Contains the word being compared
=back
=item 2. I<cond>
It is the same as L</cond>, except it also accepts a vanilla variable as valid condition, such as: C<$REQUEST_URI>, so that expression as below would work :
!$REQUEST_URI
It adds the following capture groups:
=over 4
=item I<cond_variable>
Contains the variable used in the condition, including the leading dollar or percent sign and possible surrounding accolades.
=back
=item 3. I<variable>
Same as L</variable>, but is extended to accept vanilla variable such as C<$REQUEST_URI>. In current Apache2 expressions, a variable is anoted by using percent sign and potentially surounding it with accolades. For example :
%{REQUEST_URI}
Also legacy variable includes regular expression back reference such as C<$1>, C<$2>, etc.
Its capture groups names are:
=over 8
=item I<variable>
Contains the entire variable.
=item I<varname>
Contains the variable name without dollar or percent sign no possible surrounding accolades.
=item I<var_backref>
The regular expression back reference including the dollar sign and possible surrounding accolades. For example: C<$1> or C<${1}>
=item I<rebackref>
The regular expression back reference excluding the dollar sign and possible surrounding accolades. For example: C<$1> or C<${1}> would mean I<rebackref> would contain C<1>
=item I<var_func_name>
The variable-embedded function name
=item I<var_func_args>
The variable-embedded function arguments
=back
=item 4. I<word>
I<word> is extended to also accept a regular expression back refernece such as C<$1>, C<$2>, etc.
=back
=head1 CAVEAT
Functions need to have their arguments enclosed in parenthesis. For example:
%{REMOTE_ADDR} -in split s/.*?IP Address:([^,]+)/$1/, PeerExtList('subjectAltName')
will not work, but the following will:
%{REMOTE_ADDR} -in split(s/.*?IP Address:([^,]+)/$1/, PeerExtList('subjectAltName'))
Maybe this will be adjusted in future versions.
=head1 CHANGES & CONTRIBUTIONS
Feel free to reach out to the author for possible corrections, improvements, or suggestions.
=head1 AUTHOR
Jacques Deguest E<lt>F<jack@deguest.jp>E<gt>
=head1 SEE ALSO
L<https://httpd.apache.org/docs/current/expr.html> and
L<https://httpd.apache.org/docs/trunk/en/expr.html>
=head1 COPYRIGHT & LICENSE
Copyright (c) 2020 DEGUEST Pte. Ltd.
You can use, copy, modify and redistribute this package and associated
files under the same terms as Perl itself.
=cut