%%
%% This is file `l3regex.sty',
%% generated with the docstrip utility.
%%
%% The original source files were:
%%
%% l3regex.dtx  (with options: `package')
%% 
%% EXPERIMENTAL CODE
%% 
%% Do not distribute this file without also distributing the
%% source files specified above.
%% 
%% Do not distribute a modified version of this file.
%% 
%% File: l3regex.dtx Copyright (C) 2011-2014 The LaTeX3 Project
%%
%% It may be distributed and/or modified under the conditions of the
%% LaTeX Project Public License (LPPL), either version 1.3c of this
%% license or (at your option) any later version.  The latest version
%% of this license is in the file
%%
%%    http://www.latex-project.org/lppl.txt
%%
%% This file is part of the "l3experimental bundle" (The Work in LPPL)
%% and all files in that bundle must be distributed together.
%%
%% The released version of this bundle is available from CTAN.
%%
%% -----------------------------------------------------------------------
%%
%% The development version of the bundle can be found at
%%
%%    http://www.latex-project.org/svnroot/experimental/trunk/
%%
%% for those people who are interested.
%%
%%%%%%%%%%%
%% NOTE: %%
%%%%%%%%%%%
%%
%%   Snapshots taken from the repository represent work in progress and may
%%   not work or may contain conflicting material!  We therefore ask
%%   people _not_ to put them into distributions, archives, etc. without
%%   prior consultation with the LaTeX3 Project.
%%
%% -----------------------------------------------------------------------
\RequirePackage{expl3}[2014/11/25]
\@ifpackagelater{expl3}{2014/11/25}
  {}
  {%
    \PackageError{l3regex}{Support package l3kernel too old}
      {%
        Please install an up to date version of l3kernel\MessageBreak
        using your TeX package manager or from CTAN.\MessageBreak
        \MessageBreak
        Loading l3regex will abort!%
      }%
    \endinput
  }
\GetIdInfo$Id: l3regex.dtx 5471 2014-11-25 20:11:29Z joseph $
  {L3 Experimental regular expressions}
\ProvidesExplPackage
  {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription}
\RequirePackage{l3tl-build, l3tl-analysis, l3flag, l3str, l3str-convert}
\cs_generate_variant:Nn \tl_to_str:n { V }
\cs_new:Npn \__regex_tmp:w { }
\tl_new:N   \l__regex_internal_a_tl
\tl_new:N   \l__regex_internal_b_tl
\int_new:N  \l__regex_internal_a_int
\int_new:N  \l__regex_internal_b_int
\int_new:N  \l__regex_internal_c_int
\bool_new:N \l__regex_internal_bool
\seq_new:N  \l__regex_internal_seq
\tl_new:N   \g__regex_internal_tl
\tl_const:Nn \c__regex_no_match_regex
  {
    \__regex_branch:n
      { \__regex_class:NnnnN \c_true_bool { } { 1 } { 0 } \c_true_bool }
  }
\int_new:N \l__regex_balance_int
\tl_new:N \l__regex_cs_name_tl
\cs_new_protected:Npn \__regex_break_true:w
   #1 \__regex_break_point:TF #2 #3 {#2}
\cs_new_protected:Npn \__regex_break_point:TF #1 #2 { #2 }
\cs_new_protected:Npn \__regex_item_reverse:n #1
  {
    #1
    \__regex_break_point:TF { } \__regex_break_true:w
  }
\cs_new_protected:Npn \__regex_item_caseful_equal:n #1
  {
    \if_int_compare:w #1 = \l__regex_current_char_int
      \exp_after:wN \__regex_break_true:w
    \fi:
  }
\cs_new_protected:Npn \__regex_item_caseful_range:nn #1 #2
  {
    \reverse_if:N \if_int_compare:w #1 > \l__regex_current_char_int
      \reverse_if:N \if_int_compare:w #2 < \l__regex_current_char_int
        \exp_after:wN \exp_after:wN \exp_after:wN \__regex_break_true:w
      \fi:
    \fi:
  }
\cs_new_protected:Npn \__regex_item_caseless_equal:n #1
  {
    \if_int_compare:w #1 = \l__regex_current_char_int
      \exp_after:wN \__regex_break_true:w
    \fi:
    \if_int_compare:w \l__regex_case_changed_char_int = \c_max_int
      \__regex_compute_case_changed_char:
    \fi:
    \if_int_compare:w #1 = \l__regex_case_changed_char_int
      \exp_after:wN \__regex_break_true:w
    \fi:
  }
\cs_new_protected:Npn \__regex_item_caseless_range:nn #1 #2
  {
    \reverse_if:N \if_int_compare:w #1 > \l__regex_current_char_int
      \reverse_if:N \if_int_compare:w #2 < \l__regex_current_char_int
        \exp_after:wN \exp_after:wN \exp_after:wN \__regex_break_true:w
      \fi:
    \fi:
    \if_int_compare:w \l__regex_case_changed_char_int = \c_max_int
      \__regex_compute_case_changed_char:
    \fi:
    \reverse_if:N \if_int_compare:w #1 > \l__regex_case_changed_char_int
      \reverse_if:N \if_int_compare:w #2 < \l__regex_case_changed_char_int
        \exp_after:wN \exp_after:wN \exp_after:wN \__regex_break_true:w
      \fi:
    \fi:
  }
\cs_new_protected_nopar:Npn \__regex_compute_case_changed_char:
  {
    \int_set_eq:NN \l__regex_case_changed_char_int \l__regex_current_char_int
    \if_int_compare:w \l__regex_current_char_int < \c_ninety_one
      \if_int_compare:w \l__regex_current_char_int < \c_sixty_five
      \else:
        \int_add:Nn \l__regex_case_changed_char_int { \c_thirty_two }
      \fi:
    \else:
      \if_int_compare:w \l__regex_current_char_int < \c_one_hundred_twenty_three
        \if_int_compare:w \l__regex_current_char_int < \c_ninety_seven
        \else:
          \int_sub:Nn \l__regex_case_changed_char_int { \c_thirty_two }
        \fi:
      \fi:
    \fi:
  }
\cs_new_eq:NN \__regex_item_equal:n ?
\cs_new_eq:NN \__regex_item_range:nn ?
\cs_new_protected:Npn \__regex_item_catcode:
  {
    "
    \if_case:w \l__regex_current_catcode_int
         1       \or: 4       \or: 10      \or: 40
    \or: 100     \or:         \or: 1000    \or: 4000
    \or: 10000   \or:         \or: 100000  \or: 400000
    \or: 1000000 \or: 4000000 \else: 1*\c_zero
    \fi:
  }
\cs_new_protected:Npn \__regex_item_catcode:nT #1
  {
    \if_int_odd:w \__int_eval:w #1 / \__regex_item_catcode: \__int_eval_end:
      \exp_after:wN \use:n
    \else:
      \exp_after:wN \use_none:n
    \fi:
  }
\cs_new_protected:Npn \__regex_item_catcode_reverse:nT #1#2
  { \__regex_item_catcode:nT {#1} { \__regex_item_reverse:n {#2} } }
\cs_new_protected:Npn \__regex_item_exact:nn #1#2
  {
    \if_int_compare:w #1 = \l__regex_current_catcode_int
      \if_int_compare:w #2 = \l__regex_current_char_int
        \exp_after:wN \exp_after:wN \exp_after:wN \__regex_break_true:w
      \fi:
    \fi:
  }
\cs_new_protected:Npn \__regex_item_exact_cs:c #1
  {
    \int_compare:nNnTF \l__regex_current_catcode_int = \c_zero
      {
        \str_if_eq_x:nnTF
          {
            \exp_after:wN \exp_after:wN \exp_after:wN \cs_to_str:N
            \tex_the:D \tex_toks:D \l__regex_current_pos_int
          }
          { #1 }
          { \__regex_break_true:w } { }
      }
      { }
  }
\cs_new_protected:Npn \__regex_item_cs:n #1
  {
    \int_compare:nNnT \l__regex_current_catcode_int = \c_zero
      {
        \group_begin:
          \tl_set:Nx \l__regex_cs_name_tl
            {
              \exp_after:wN \exp_after:wN
              \exp_after:wN \cs_to_str:N
              \tex_the:D \tex_toks:D \l__regex_current_pos_int
            }
          \__regex_single_match:
          \__regex_disable_submatches:
          \__regex_build_for_cs:n {#1}
          \bool_set_eq:NN \l__regex_saved_success_bool \g__regex_success_bool
          \exp_args:NV \__regex_match:n \l__regex_cs_name_tl
          \if_meaning:w \c_true_bool \g__regex_success_bool
            \group_insert_after:N \__regex_break_true:w
          \fi:
          \bool_gset_eq:NN \g__regex_success_bool \l__regex_saved_success_bool
        \group_end:
      }
  }
\cs_new_protected_nopar:Npn \__regex_prop_d:
  { \__regex_item_caseful_range:nn \c_forty_eight { 57 } } % 0--9
\cs_new_protected_nopar:Npn \__regex_prop_h:
  {
    \__regex_item_caseful_equal:n \c_thirty_two % space
    \__regex_item_caseful_equal:n \c_nine       % tab
  }
\cs_new_protected_nopar:Npn \__regex_prop_s:
  {
    \__regex_item_caseful_equal:n \c_thirty_two % space
    \__regex_item_caseful_equal:n \c_nine       % tab
    \__regex_item_caseful_equal:n \c_ten        % lf
    \__regex_item_caseful_equal:n \c_twelve     % ff
    \__regex_item_caseful_equal:n \c_thirteen   % cr
  }
\cs_new_protected_nopar:Npn \__regex_prop_v:
  { \__regex_item_caseful_range:nn \c_ten \c_thirteen } % lf, vtab, ff, cr
\cs_new_protected_nopar:Npn \__regex_prop_w:
  {
    \__regex_item_caseful_range:nn \c_ninety_seven { 122 } % a--z
    \__regex_item_caseful_range:nn \c_sixty_five   {  90 } % A--Z
    \__regex_item_caseful_range:nn \c_forty_eight  {  57 } % 0--9
    \__regex_item_caseful_equal:n  { 95 } % _
  }
\cs_new_protected_nopar:Npn \__regex_prop_N:
  { \__regex_item_reverse:n { \__regex_item_caseful_equal:n \c_ten } }
\cs_new_protected_nopar:Npn \__regex_posix_alnum:
  { \__regex_posix_alpha: \__regex_posix_digit: }
\cs_new_protected_nopar:Npn \__regex_posix_alpha:
  { \__regex_posix_lower: \__regex_posix_upper: }
\cs_new_protected_nopar:Npn \__regex_posix_ascii:
  { \__regex_item_caseful_range:nn \c_zero \c_one_hundred_twenty_seven }
\cs_new_eq:NN \__regex_posix_blank: \__regex_prop_h:
\cs_new_protected_nopar:Npn \__regex_posix_cntrl:
  {
    \__regex_item_caseful_range:nn \c_zero { 31 }
    \__regex_item_caseful_equal:n \c_one_hundred_twenty_seven
  }
\cs_new_eq:NN \__regex_posix_digit: \__regex_prop_d:
\cs_new_protected_nopar:Npn \__regex_posix_graph:
  { \__regex_item_caseful_range:nn { 33 } { 126 } }
\cs_new_protected_nopar:Npn \__regex_posix_lower:
  { \__regex_item_caseful_range:nn \c_ninety_seven { 122 } }
\cs_new_protected_nopar:Npn \__regex_posix_print:
  { \__regex_item_caseful_range:nn \c_thirty_two { 126 } }
\cs_new_protected_nopar:Npn \__regex_posix_punct:
  {
    \__regex_item_caseful_range:nn { 33 } { 47 }
    \__regex_item_caseful_range:nn { 58 } { 64 }
    \__regex_item_caseful_range:nn { 91 } { 96 }
    \__regex_item_caseful_range:nn { 123 } { 126 }
  }
\cs_new_protected_nopar:Npn \__regex_posix_space:
  {
    \__regex_item_caseful_equal:n \c_thirty_two
    \__regex_item_caseful_range:nn \c_nine \c_thirteen
  }
\cs_new_protected_nopar:Npn \__regex_posix_upper:
  { \__regex_item_caseful_range:nn \c_sixty_five { 90 } }
\cs_new_eq:NN \__regex_posix_word: \__regex_prop_w:
\cs_new_protected_nopar:Npn \__regex_posix_xdigit:
  {
    \__regex_posix_digit:
    \__regex_item_caseful_range:nn \c_sixty_five { 70 }
    \__regex_item_caseful_range:nn \c_ninety_seven { 102 }
  }
\cs_new_protected:Npn \__regex_escape_use:nnnn #1#2#3#4
  {
    \__tl_build:Nw \l__regex_internal_a_tl
      \cs_set_nopar:Npn \__regex_escape_unescaped:N ##1 { #1 }
      \cs_set_nopar:Npn \__regex_escape_escaped:N ##1 { #2 }
      \cs_set_nopar:Npn \__regex_escape_raw:N ##1 { #3 }
      \int_set:Nn \tex_escapechar:D { 92 }
      \__str_gset_other:Nn \g__regex_internal_tl { #4 }
      \tl_set:Nx \l__regex_internal_b_tl
        {
          \exp_after:wN \__regex_escape_loop:N \g__regex_internal_tl
          { break } \__prg_break_point:
        }
      \__tl_build_one:o \l__regex_internal_b_tl
    \__tl_build_end:
    \l__regex_internal_a_tl
  }
\cs_new:Npn \__regex_escape_loop:N #1
  {
    \cs_if_exist_use:cF { __regex_escape_\token_to_str:N #1:w }
      { \__regex_escape_unescaped:N #1 }
    \__regex_escape_loop:N
  }
\cs_new_nopar:cpn { __regex_escape_ \c_backslash_str :w }
    \__regex_escape_loop:N #1
  {
    \cs_if_exist_use:cF { __regex_escape_/\token_to_str:N #1:w }
      { \__regex_escape_escaped:N #1 }
    \__regex_escape_loop:N
  }
\cs_new_eq:NN \__regex_escape_unescaped:N ?
\cs_new_eq:NN \__regex_escape_escaped:N   ?
\cs_new_eq:NN \__regex_escape_raw:N       ?
\cs_new_eq:NN \__regex_escape_break:w \__prg_break:
\cs_new_nopar:cpn { __regex_escape_/break:w }
  {
    \if_false: { \fi: }
    \__msg_kernel_error:nn { regex } { trailing-backslash }
    \exp_after:wN \use_none:n \exp_after:wN { \if_false: } \fi:
  }
\cs_new_nopar:cpn { __regex_escape_~:w } { }
\cs_new_nopar:cpx { __regex_escape_/a:w }
  { \exp_not:N \__regex_escape_raw:N \iow_char:N \^^G }
\cs_new_nopar:cpx { __regex_escape_/t:w }
  { \exp_not:N \__regex_escape_raw:N \iow_char:N \^^I }
\cs_new_nopar:cpx { __regex_escape_/n:w }
  { \exp_not:N \__regex_escape_raw:N \iow_char:N \^^J }
\cs_new_nopar:cpx { __regex_escape_/f:w }
  { \exp_not:N \__regex_escape_raw:N \iow_char:N \^^L }
\cs_new_nopar:cpx { __regex_escape_/r:w }
  { \exp_not:N \__regex_escape_raw:N \iow_char:N \^^M }
\cs_new_nopar:cpx { __regex_escape_/e:w }
  { \exp_not:N \__regex_escape_raw:N \iow_char:N \^^[ }
\cs_new:cpn { __regex_escape_/x:w } \__regex_escape_loop:N
  {
    \exp_after:wN \__regex_escape_x_end:w
    \__int_value:w "0 \__regex_escape_x_test:N
  }
\cs_new:Npn \__regex_escape_x_end:w #1 ;
  {
    \int_compare:nNnTF {#1} < \c_two_hundred_fifty_six
      {
        \exp_last_unbraced:Nf \__regex_escape_raw:N
          { \__str_output_byte:n {#1} }
      }
      { \__regex_escape_x_large:n {#1} }
  }
\group_begin:
  \char_set_catcode_other:n { 0 }
  \cs_new:Npn \__regex_escape_x_large:n #1
    {
      \if_false: { \fi: }
      \__tl_build_one:o \l__regex_internal_b_tl
      \int_compare:nNnTF {#1} > \c_max_char_int
        {
          \__msg_kernel_error:nnx { regex } { x-overflow } {#1}
          \tl_set:Nx \l__regex_internal_b_tl
            { \if_false: } \fi:
        }
        {
          \char_set_lccode:nn { \c_zero } {#1}
          \tl_to_lowercase:n
            {
              \tl_set:Nx \l__regex_internal_b_tl
                { \if_false: } \fi:
                \__regex_escape_raw:N ^^@
            }
        }
    }
\group_end:
\cs_new:Npn \__regex_escape_x_test:N #1
  {
    \str_if_eq_x:nnTF {#1} { break } { ; }
      {
        \if_charcode:w \c_space_token #1
          \exp_after:wN \__regex_escape_x_test:N
        \else:
          \exp_after:wN \__regex_escape_x_testii:N
          \exp_after:wN #1
        \fi:
      }
  }
\cs_new:Npn \__regex_escape_x_testii:N #1
  {
    \if_charcode:w \c_left_brace_str #1
      \exp_after:wN \__regex_escape_x_loop:N
    \else:
      \__str_hexadecimal_use:NTF #1
        { \exp_after:wN \__regex_escape_x:N }
        { ; \exp_after:wN \__regex_escape_loop:N \exp_after:wN #1 }
    \fi:
  }
\cs_new:Npn \__regex_escape_x:N #1
  {
    \str_if_eq_x:nnTF {#1} { break } { ; }
      {
        \__str_hexadecimal_use:NTF #1
          { ; \__regex_escape_loop:N }
          { ; \__regex_escape_loop:N #1 }
      }
  }
\cs_new:Npn \__regex_escape_x_loop:N #1
  {
    \str_if_eq_x:nnTF {#1} { break }
      { ; \__regex_escape_x_loop_error:n { } {#1} }
      {
        \__str_hexadecimal_use:NTF #1
          { \__regex_escape_x_loop:N }
          {
            \token_if_eq_charcode:NNTF \c_space_token #1
              { \__regex_escape_x_loop:N }
              {
                ;
                \exp_after:wN
                \token_if_eq_charcode:NNTF \c_right_brace_str #1
                  { \__regex_escape_loop:N }
                  { \__regex_escape_x_loop_error:n {#1} }
              }
          }
      }
  }
\cs_new:Npn \__regex_escape_x_loop_error:n #1
  {
    \if_false: { \fi: }
    \__tl_build_one:o \l__regex_internal_b_tl
    \__msg_kernel_error:nnx { regex } { x-missing-rbrace } {#1}
    \tl_set:Nx \l__regex_internal_b_tl
      { \if_false: } \fi: \__regex_escape_loop:N #1
  }
\prg_new_conditional:Npnn \__regex_char_if_special:N #1 { TF }
  {
    \if_int_compare:w `#1 < \c_ninety_one
      \if_int_compare:w `#1 < \c_fifty_eight
        \if_int_compare:w `#1 < \c_forty_eight
          \if_int_compare:w `#1 < \c_thirty_two
            \prg_return_false: \else: \prg_return_true: \fi:
        \else: \prg_return_false: \fi:
      \else:
        \if_int_compare:w `#1 < \c_sixty_five
          \prg_return_true: \else: \prg_return_false: \fi:
      \fi:
    \else:
      \if_int_compare:w `#1 < \c_one_hundred_twenty_three
        \if_int_compare:w `#1 < \c_ninety_seven
          \prg_return_true: \else: \prg_return_false: \fi:
      \else:
        \if_int_compare:w `#1 < \c_one_hundred_twenty_seven
          \prg_return_true: \else: \prg_return_false: \fi:
      \fi:
    \fi:
  }
\prg_new_conditional:Npnn \__regex_char_if_alphanumeric:N #1 { TF }
  {
    \if_int_compare:w `#1 < \c_ninety_one
      \if_int_compare:w `#1 < \c_fifty_eight
        \if_int_compare:w `#1 < \c_forty_eight
          \prg_return_false: \else: \prg_return_true: \fi:
      \else:
        \if_int_compare:w `#1 < \c_sixty_five
          \prg_return_false: \else: \prg_return_true: \fi:
      \fi:
    \else:
      \if_int_compare:w `#1 < \c_one_hundred_twenty_three
        \if_int_compare:w `#1 < \c_ninety_seven
          \prg_return_false: \else: \prg_return_true: \fi:
      \else:
        \prg_return_false:
      \fi:
    \fi:
  }
\int_new:N \l__regex_group_level_int
\int_new:N \l__regex_mode_int
\int_new:N \l__regex_catcodes_int
\int_new:N \l__regex_default_catcodes_int
\bool_new:N \l__regex_catcodes_bool
\int_const:Nn \c__regex_catcode_C_int { "1 }
\int_const:Nn \c__regex_catcode_B_int { "4 }
\int_const:Nn \c__regex_catcode_E_int { "10 }
\int_const:Nn \c__regex_catcode_M_int { "40 }
\int_const:Nn \c__regex_catcode_T_int { "100 }
\int_const:Nn \c__regex_catcode_P_int { "1000 }
\int_const:Nn \c__regex_catcode_U_int { "4000 }
\int_const:Nn \c__regex_catcode_D_int { "10000 }
\int_const:Nn \c__regex_catcode_S_int { "100000 }
\int_const:Nn \c__regex_catcode_L_int { "400000 }
\int_const:Nn \c__regex_catcode_O_int { "1000000 }
\int_const:Nn \c__regex_catcode_A_int { "4000000 }
\int_const:Nn \c__regex_all_catcodes_int { "5515155 }
\cs_new_eq:NN \l__regex_internal_regex \c__regex_no_match_regex
\seq_new:N \l__regex_show_prefix_seq
\int_new:N \l__regex_show_lines_int
\cs_new_protected:Npn \__regex_get_digits:NTFw #1#2#3#4#5
  {
    \__regex_if_raw_digit:NNTF #4 #5
      { #1 = #5 \__regex_get_digits_loop:nw {#2} }
      { #3 #4 #5 }
  }
\cs_new:Npn \__regex_get_digits_loop:nw #1#2#3
  {
    \__regex_if_raw_digit:NNTF #2 #3
      { #3 \__regex_get_digits_loop:nw {#1} }
      { \scan_stop: #1 #2 #3 }
  }
\prg_new_conditional:Npnn \__regex_if_raw_digit:NN #1#2 { TF }
  {
    \if_meaning:w \__regex_compile_raw:N #1
      \if_int_compare:w \c_one < 1 #2 \exp_stop_f:
        \prg_return_true:
      \else:
        \prg_return_false:
      \fi:
    \else:
      \prg_return_false:
    \fi:
  }
\cs_new_nopar:Npn \__regex_if_in_class:TF
  {
    \if_int_odd:w \l__regex_mode_int
      \exp_after:wN \use_i:nn
    \else:
      \exp_after:wN \use_ii:nn
    \fi:
  }
\cs_new_nopar:Npn \__regex_if_in_cs:TF
  {
    \if_int_odd:w \l__regex_mode_int
      \exp_after:wN \use_ii:nn
    \else:
      \if_int_compare:w \l__regex_mode_int < \c_zero
        \exp_after:wN \exp_after:wN \exp_after:wN \use_i:nn
      \else:
        \exp_after:wN \exp_after:wN \exp_after:wN \use_ii:nn
      \fi:
    \fi:
  }
\cs_new_nopar:Npn \__regex_if_in_class_or_catcode:TF
  {
    \if_int_odd:w \l__regex_mode_int
      \exp_after:wN \use_i:nn
    \else:
      \if_int_compare:w \l__regex_mode_int > \c_zero
        \exp_after:wN \exp_after:wN \exp_after:wN \use_i:nn
      \else:
        \exp_after:wN \exp_after:wN \exp_after:wN \use_ii:nn
      \fi:
    \fi:
  }
\cs_new_nopar:Npn \__regex_if_within_catcode:TF
  {
    \if_int_compare:w \l__regex_mode_int > \c_zero
      \exp_after:wN \use_i:nn
    \else:
      \exp_after:wN \use_ii:nn
    \fi:
  }
\cs_new_protected:Npn \__regex_chk_c_allowed:T
  {
    \if_int_compare:w \l__regex_mode_int = \c_zero
      \exp_after:wN \use:n
    \else:
      \if_int_compare:w \l__regex_mode_int = \c_three
        \exp_after:wN \exp_after:wN \exp_after:wN \use:n
      \else:
        \__msg_kernel_error:nn { regex } { c-bad-mode }
        \exp_after:wN \exp_after:wN \exp_after:wN \use_none:n
      \fi:
    \fi:
  }
\cs_new_protected:Npn \__regex_mode_quit_c:
  {
    \if_int_compare:w \l__regex_mode_int = \c_two
      \l__regex_mode_int = \c_zero
    \else:
      \if_int_compare:w \l__regex_mode_int = \c_six
        \l__regex_mode_int = \c_three
      \fi:
    \fi:
  }
\cs_new_protected_nopar:Npn \__regex_compile:w
  {
    \__tl_build_x:Nw \l__regex_internal_regex
      \int_zero:N \l__regex_group_level_int
      \int_set_eq:NN \l__regex_default_catcodes_int \c__regex_all_catcodes_int
      \int_set_eq:NN \l__regex_catcodes_int \l__regex_default_catcodes_int
      \cs_set_nopar:Npn \__regex_item_equal:n  { \__regex_item_caseful_equal:n }
      \cs_set_nopar:Npn \__regex_item_range:nn { \__regex_item_caseful_range:nn }
      \__tl_build_one:n { \__regex_branch:n { \if_false: } \fi: }
  }
\cs_new_protected_nopar:Npn \__regex_compile_end:
  {
      \__regex_if_in_class:TF
        {
          \__msg_kernel_error:nn { regex } { missing-rbrack }
          \use:c { __regex_compile_]: }
          \prg_do_nothing: \prg_do_nothing:
        }
        { }
      \if_int_compare:w \l__regex_group_level_int > \c_zero
        \__msg_kernel_error:nnx { regex } { missing-rparen }
          { \int_use:N \l__regex_group_level_int }
        \prg_replicate:nn
          { \l__regex_group_level_int }
          {
              \__tl_build_one:n
                {
                  \if_false: { \fi: }
                  \if_false: { \fi: } { 1 } { 0 } \c_true_bool
                }
            \__tl_build_end:
            \__tl_build_one:o \l__regex_internal_regex
          }
      \fi:
      \__tl_build_one:n { \if_false: { \fi: } }
    \__tl_build_end:
  }
\cs_new_protected:Npn \__regex_compile:n #1
  {
    \__regex_compile:w
      \int_set:Nn \tex_escapechar:D { 92 }
      \int_set_eq:NN \l__regex_mode_int \c_zero
      \__regex_escape_use:nnnn
        {
          \__regex_char_if_special:NTF ##1
            \__regex_compile_special:N \__regex_compile_raw:N ##1
        }
        {
          \__regex_char_if_alphanumeric:NTF ##1
            \__regex_compile_escaped:N \__regex_compile_raw:N ##1
        }
        { \__regex_compile_raw:N ##1 }
        { #1 }
      \prg_do_nothing: \prg_do_nothing:
      \prg_do_nothing: \prg_do_nothing:
      \int_compare:nNnT \l__regex_mode_int = \c_two
        { \__msg_kernel_error:nn { regex } { c-trailing } }
      \int_compare:nNnT \l__regex_mode_int < \c_zero
        {
          \__msg_kernel_error:nn { regex } { c-missing-rbrace }
          \__regex_compile_end:
          \__regex_compile_one:x
            { \__regex_item_cs:n { \exp_not:o \l__regex_internal_regex } }
          \prg_do_nothing: \prg_do_nothing:
          \prg_do_nothing: \prg_do_nothing:
        }
    \__regex_compile_end:
  }
\cs_new_protected:Npn \__regex_compile_special:N #1
  {
    \cs_if_exist_use:cF { __regex_compile_#1: }
      { \__regex_compile_raw:N #1 }
  }
\cs_new_protected:Npn \__regex_compile_escaped:N #1
  {
    \cs_if_exist_use:cF { __regex_compile_/#1: }
      { \__regex_compile_raw:N #1 }
  }
\cs_new_protected:Npn \__regex_compile_one:x #1
  {
    \__regex_mode_quit_c:
    \__regex_if_in_class:TF { }
      {
        \__tl_build_one:n
          { \__regex_class:NnnnN \c_true_bool { \if_false: } \fi: }
      }
    \__tl_build_one:x
      {
        \if_int_compare:w \l__regex_catcodes_int < \c__regex_all_catcodes_int
          \__regex_item_catcode:nT { \int_use:N \l__regex_catcodes_int }
            { \exp_not:N \exp_not:n {#1} }
        \else:
          \exp_not:N \exp_not:n {#1}
        \fi:
      }
    \int_set_eq:NN \l__regex_catcodes_int \l__regex_default_catcodes_int
    \__regex_if_in_class:TF { } { \__regex_compile_quantifier:w }
  }
\cs_new_protected:Npn \__regex_compile_abort_tokens:n #1
  {
    \use:x
      {
        \exp_args:No \tl_map_function:nN { \tl_to_str:n {#1} }
          \__regex_compile_raw:N
      }
  }
\cs_generate_variant:Nn \__regex_compile_abort_tokens:n { x }
\cs_new_protected:Npn \__regex_compile_quantifier:w #1#2
  {
    \token_if_eq_meaning:NNTF #1 \__regex_compile_special:N
      {
        \cs_if_exist_use:cF { __regex_compile_quantifier_#2:w }
          { \__regex_compile_quantifier_none: #1 #2 }
      }
      { \__regex_compile_quantifier_none: #1 #2 }
  }
\cs_new_protected:Npn \__regex_compile_quantifier_none:
  { \__tl_build_one:n { \if_false: { \fi: } { 1 } { 0 } \c_false_bool } }
\cs_new_protected:Npn \__regex_compile_quantifier_abort:xNN #1#2#3
  {
    \__regex_compile_quantifier_none:
    \__msg_kernel_warning:nnxx { regex } { invalid-quantifier } {#1} {#3}
    \__regex_compile_abort_tokens:x {#1}
    #2 #3
  }
\cs_new_protected:Npn \__regex_compile_quantifier_lazyness:nnNN #1#2#3#4
  {
    \str_if_eq:nnTF { #3 #4 } { \__regex_compile_special:N ? }
      { \__tl_build_one:n { \if_false: { \fi: } { #1 } { #2 } \c_true_bool } }
      {
        \__tl_build_one:n { \if_false: { \fi: } { #1 } { #2 } \c_false_bool }
        #3 #4
      }
  }
\cs_new_protected_nopar:cpn { __regex_compile_quantifier_?:w }
  { \__regex_compile_quantifier_lazyness:nnNN { 0 } { 1 } }
\cs_new_protected_nopar:cpn { __regex_compile_quantifier_*:w }
  { \__regex_compile_quantifier_lazyness:nnNN { 0 } { -1 } }
\cs_new_protected_nopar:cpn { __regex_compile_quantifier_+:w }
  { \__regex_compile_quantifier_lazyness:nnNN { 1 } { -1 } }
\cs_new_protected:cpn { __regex_compile_quantifier_ \c_left_brace_str :w }
  {
    \__regex_get_digits:NTFw \l__regex_internal_a_int
      { \__regex_compile_quantifier_braced_auxi:w }
      { \__regex_compile_quantifier_abort:xNN { \c_left_brace_str } }
  }
\cs_new_protected:Npn \__regex_compile_quantifier_braced_auxi:w #1#2
  {
    \str_case_x:nnn { #1 #2 }
      {
        { \__regex_compile_special:N \c_right_brace_str }
          {
            \exp_args:No \__regex_compile_quantifier_lazyness:nnNN
              { \int_use:N \l__regex_internal_a_int } { 0 }
          }
        { \__regex_compile_special:N , }
          {
            \__regex_get_digits:NTFw \l__regex_internal_b_int
              { \__regex_compile_quantifier_braced_auxiii:w }
              { \__regex_compile_quantifier_braced_auxii:w }
          }
      }
      {
        \__regex_compile_quantifier_abort:xNN
          { \c_left_brace_str \int_use:N \l__regex_internal_a_int }
        #1 #2
      }
  }
\cs_new_protected:Npn \__regex_compile_quantifier_braced_auxii:w #1#2
  {
    \str_if_eq_x:nnTF
      { #1 #2 } { \__regex_compile_special:N \c_right_brace_str }
      {
        \exp_args:No \__regex_compile_quantifier_lazyness:nnNN
          { \int_use:N \l__regex_internal_a_int } { -1 }
      }
      {
        \__regex_compile_quantifier_abort:xNN
          { \c_left_brace_str \int_use:N \l__regex_internal_a_int , }
        #1 #2
      }
  }
\cs_new_protected:Npn \__regex_compile_quantifier_braced_auxiii:w #1#2
  {
    \str_if_eq_x:nnTF
      { #1 #2 } { \__regex_compile_special:N \c_right_brace_str }
      {
        \if_int_compare:w \l__regex_internal_a_int > \l__regex_internal_b_int
          \__msg_kernel_error:nnxx { regex } { backwards-quantifier }
            { \int_use:N \l__regex_internal_a_int }
            { \int_use:N \l__regex_internal_b_int }
          \int_zero:N \l__regex_internal_b_int
        \else:
          \int_sub:Nn \l__regex_internal_b_int \l__regex_internal_a_int
        \fi:
        \exp_args:Noo \__regex_compile_quantifier_lazyness:nnNN
          { \int_use:N \l__regex_internal_a_int }
          { \int_use:N \l__regex_internal_b_int }
      }
      {
        \__regex_compile_quantifier_abort:xNN
          {
            \c_left_brace_str
            \int_use:N \l__regex_internal_a_int ,
            \int_use:N \l__regex_internal_b_int
          }
        #1 #2
      }
  }
\cs_new_protected:Npn \__regex_compile_raw_error:N #1
  {
    \__msg_kernel_error:nnx { regex } { bad-escape } {#1}
    \__regex_compile_raw:N #1
  }
\cs_new_protected:Npn \__regex_compile_raw:N #1#2#3
  {
    \__regex_if_in_class:TF
      {
        \str_if_eq:nnTF {#2#3} { \__regex_compile_special:N - }
          { \__regex_compile_range:Nw #1 }
          {
            \__regex_compile_one:x
              { \__regex_item_equal:n { \__int_value:w `#1 ~ } }
            #2 #3
          }
      }
      {
        \__regex_compile_one:x
          { \__regex_item_equal:n { \__int_value:w `#1 ~ } }
        #2 #3
      }
  }
\prg_new_protected_conditional:Npnn \__regex_if_end_range:NN #1#2 { TF }
  {
    \if_meaning:w \__regex_compile_raw:N #1
      \prg_return_true:
    \else:
      \if_meaning:w \__regex_compile_special:N #1
        \if_charcode:w ] #2
          \prg_return_false:
        \else:
          \prg_return_true:
        \fi:
      \else:
        \prg_return_false:
      \fi:
    \fi:
  }
\cs_new_protected:Npn \__regex_compile_range:Nw #1#2#3
  {
    \__regex_if_end_range:NNTF #2 #3
      {
        \if_int_compare:w `#1 > `#3 \exp_stop_f:
          \__msg_kernel_error:nnxx { regex } { range-backwards } {#1} {#3}
        \else:
          \__tl_build_one:x
            {
              \if_int_compare:w `#1 = `#3 \exp_stop_f:
                \__regex_item_equal:n
              \else:
                \__regex_item_range:nn { \__int_value:w `#1 ~ }
              \fi:
              { \__int_value:w `#3 ~ }
            }
        \fi:
      }
      {
        \__msg_kernel_warning:nnxx { regex } { range-missing-end }
          {#1} { \c_backslash_str #3 }
        \__tl_build_one:x
          {
            \__regex_item_equal:n { \__int_value:w `#1 ~ }
            \__regex_item_equal:n { \__int_value:w `- ~ }
          }
        #2#3
      }
  }
\cs_new_protected_nopar:cpx { __regex_compile_.: }
  {
    \exp_not:N \__regex_if_in_class:TF
      { \__regex_compile_raw:N . }
      { \__regex_compile_one:x \exp_not:c { __regex_prop_.: } }
  }
\cs_new_protected_nopar:cpn { __regex_prop_.: }
  {
    \if_int_compare:w \l__regex_current_char_int > - \c_two
      \exp_after:wN \__regex_break_true:w
    \fi:
  }
\cs_set_protected:Npn \__regex_tmp:w #1#2
  {
    \cs_new_protected_nopar:cpx { __regex_compile_/#1: }
      { \__regex_compile_one:x \exp_not:c { __regex_prop_#1: } }
    \cs_new_protected_nopar:cpx { __regex_compile_/#2: }
      {
        \__regex_compile_one:x
          { \__regex_item_reverse:n \exp_not:c { __regex_prop_#1: } }
      }
  }
\__regex_tmp:w d D
\__regex_tmp:w h H
\__regex_tmp:w s S
\__regex_tmp:w v V
\__regex_tmp:w w W
\cs_new_protected_nopar:cpn { __regex_compile_/N: }
  { \__regex_compile_one:x \__regex_prop_N: }
\cs_new_protected:Npn \__regex_compile_anchor:NF #1#2
  {
    \__regex_if_in_class_or_catcode:TF {#2}
      {
        \__tl_build_one:n
          { \__regex_assertion:Nn \c_true_bool { \__regex_anchor:N #1 } }
      }
  }
\cs_set_protected:Npn \__regex_tmp:w #1#2
  {
    \cs_new_protected_nopar:cpn { __regex_compile_/#1: }
      { \__regex_compile_anchor:NF #2 { \__regex_compile_raw_error:N #1 } }
  }
\__regex_tmp:w A \l__regex_min_pos_int
\__regex_tmp:w G \l__regex_start_pos_int
\__regex_tmp:w Z \l__regex_max_pos_int
\__regex_tmp:w z \l__regex_max_pos_int
\cs_set_protected:Npn \__regex_tmp:w #1#2
  {
    \cs_new_protected_nopar:cpn { __regex_compile_#1: }
      { \__regex_compile_anchor:NF #2 { \__regex_compile_raw:N #1 } }
  }
\exp_args:Nx \__regex_tmp:w { \iow_char:N \^ } \l__regex_min_pos_int
\exp_args:Nx \__regex_tmp:w { \iow_char:N \$ } \l__regex_max_pos_int
\cs_new_protected_nopar:cpn { __regex_compile_/b: }
  {
    \__regex_if_in_class_or_catcode:TF
      { \__regex_compile_raw_error:N b }
      {
        \__tl_build_one:n
          { \__regex_assertion:Nn \c_true_bool { \__regex_b_test: } }
      }
  }
\cs_new_protected_nopar:cpn { __regex_compile_/B: }
  {
    \__regex_if_in_class_or_catcode:TF
      { \__regex_compile_raw_error:N B }
      {
        \__tl_build_one:n
          { \__regex_assertion:Nn \c_false_bool { \__regex_b_test: } }
      }
  }
\cs_new_protected:cpn { __regex_compile_]: }
  {
    \__regex_if_in_class:TF
      {
        \if_int_compare:w \l__regex_mode_int > \c_sixteen
          \__tl_build_one:n { \if_false: { \fi: } }
        \fi:
        \tex_advance:D \l__regex_mode_int - \c_fifteen
        \tex_divide:D \l__regex_mode_int \c_thirteen
        \if_int_odd:w \l__regex_mode_int \else:
          \exp_after:wN \__regex_compile_quantifier:w
        \fi:
      }
      { \__regex_compile_raw:N ] }
  }
\cs_new_protected_nopar:cpn { __regex_compile_[: }
  {
    \__regex_if_in_class:TF
      { \__regex_compile_class_posix_test:w }
      {
        \__regex_if_within_catcode:TF
          {
            \exp_after:wN \__regex_compile_class_catcode:w
              \int_use:N \l__regex_catcodes_int ;
          }
          { \__regex_compile_class_normal:w }
      }
  }
\cs_new_protected_nopar:Npn \__regex_compile_class_normal:w
  {
    \__regex_compile_class:TFNN
      { \__regex_class:NnnnN \c_true_bool }
      { \__regex_class:NnnnN \c_false_bool }
  }
\cs_new_protected:Npn \__regex_compile_class_catcode:w #1;
  {
    \if_int_compare:w \l__regex_mode_int = \c_two
      \__tl_build_one:n
        { \__regex_class:NnnnN \c_true_bool { \if_false: } \fi: }
    \fi:
    \int_set_eq:NN \l__regex_catcodes_int \l__regex_default_catcodes_int
    \__regex_compile_class:TFNN
      { \__regex_item_catcode:nT {#1} }
      { \__regex_item_catcode_reverse:nT {#1} }
  }
\cs_new_protected:Npn \__regex_compile_class:TFNN #1#2#3#4
  {
    \l__regex_mode_int = \__int_value:w \l__regex_mode_int 3 \exp_stop_f:
    \str_if_eq:nnTF { #3 #4 } { \__regex_compile_special:N ^ }
      {
        \__tl_build_one:n { #2 { \if_false: } \fi: }
        \__regex_compile_class:NN
      }
      {
        \__tl_build_one:n { #1 { \if_false: } \fi: }
        \__regex_compile_class:NN #3 #4
      }
  }
\cs_new_protected:Npn \__regex_compile_class:NN #1#2
  {
    \token_if_eq_charcode:NNTF #2 ]
      { \__regex_compile_raw:N #2 }
      { #1 #2 }
  }
\cs_new_protected:Npn \__regex_compile_class_posix_test:w #1#2
  {
    \token_if_eq_meaning:NNT \__regex_compile_special:N #1
      {
        \str_case:nn { #2 }
          {
            : { \__regex_compile_class_posix:NNNNw }
            = { \__msg_kernel_warning:nnx { regex } { posix-unsupported } { = } }
            . { \__msg_kernel_warning:nnx { regex } { posix-unsupported } { . } }
          }
      }
    \__regex_compile_raw:N [ #1 #2
  }
\cs_new_protected:Npn \__regex_compile_class_posix:NNNNw #1#2#3#4#5#6
  {
    \str_if_eq:nnTF { #5 #6 } { \__regex_compile_special:N ^ }
      {
        \bool_set_false:N \l__regex_internal_bool
        \tl_set:Nx \l__regex_internal_a_tl { \if_false: } \fi:
          \__regex_compile_class_posix_loop:w
      }
      {
        \bool_set_true:N \l__regex_internal_bool
        \tl_set:Nx \l__regex_internal_a_tl { \if_false: } \fi:
          \__regex_compile_class_posix_loop:w #5 #6
      }
  }
\cs_new:Npn \__regex_compile_class_posix_loop:w #1#2
  {
    \token_if_eq_meaning:NNTF \__regex_compile_raw:N #1
      { #2 \__regex_compile_class_posix_loop:w }
      { \if_false: { \fi: } \__regex_compile_class_posix_end:w #1 #2 }
  }
\cs_new_protected:Npn \__regex_compile_class_posix_end:w #1#2#3#4
  {
    \str_if_eq:nnTF { #1 #2 #3 #4 }
      { \__regex_compile_special:N : \__regex_compile_special:N ] }
      {
        \cs_if_exist:cTF { __regex_posix_ \l__regex_internal_a_tl : }
          {
            \__regex_compile_one:x
              {
                \bool_if:NF \l__regex_internal_bool \__regex_item_reverse:n
                \exp_not:c { __regex_posix_ \l__regex_internal_a_tl : }
              }
          }
          {
            \__msg_kernel_warning:nnx { regex } { posix-unknown }
              { \l__regex_internal_a_tl }
            \__regex_compile_abort_tokens:x
              {
                [: \bool_if:NF \l__regex_internal_bool { ^ }
                \l__regex_internal_a_tl :]
              }
          }
      }
      {
        \__msg_kernel_error:nnxx { regex } { posix-missing-close }
          { [: \l__regex_internal_a_tl } { #2 #4 }
        \__regex_compile_abort_tokens:x { [: \l__regex_internal_a_tl }
        #1 #2 #3 #4
      }
  }
\cs_new_protected:Npn \__regex_compile_group_begin:N #1
  {
    \__tl_build_one:n { #1 { \if_false: } \fi: }
    \__regex_mode_quit_c:
    \__tl_build:Nw \l__regex_internal_regex
      \int_set_eq:NN \l__regex_default_catcodes_int \l__regex_catcodes_int
      \int_incr:N \l__regex_group_level_int
      \__tl_build_one:n { \__regex_branch:n { \if_false: } \fi: }
  }
\cs_new_protected:Npn \__regex_compile_group_end:
  {
    \if_int_compare:w \l__regex_group_level_int > \c_zero
        \__tl_build_one:n { \if_false: { \fi: } }
      \__tl_build_end:
      \int_set_eq:NN \l__regex_catcodes_int \l__regex_default_catcodes_int
      \__tl_build_one:o \l__regex_internal_regex
      \exp_after:wN \__regex_compile_quantifier:w
    \else:
      \__msg_kernel_warning:nn { regex } { extra-rparen }
      \exp_after:wN \__regex_compile_raw:N \exp_after:wN )
    \fi:
  }
\cs_new_protected_nopar:cpn { __regex_compile_(: }
  {
    \__regex_if_in_class:TF { \__regex_compile_raw:N ( }
      { \__regex_compile_lparen:w }
  }
\cs_new_protected:Npn \__regex_compile_lparen:w #1#2#3#4
  {
    \str_if_eq:nnTF { #1 #2 } { \__regex_compile_special:N ? }
      {
        \cs_if_exist_use:cF
          { __regex_compile_special_group_\token_to_str:N #4 :w }
          {
            \__msg_kernel_warning:nnx { regex } { special-group-unknown }
              { (? #4 }
            \__regex_compile_group_begin:N \__regex_group:nnnN
              \__regex_compile_raw:N ? #3 #4
          }
      }
      {
        \__regex_compile_group_begin:N \__regex_group:nnnN
          #1 #2 #3 #4
      }
  }
\cs_new_protected_nopar:cpn { __regex_compile_|: }
  {
    \__regex_if_in_class:TF { \__regex_compile_raw:N | }
      {
        \__tl_build_one:n
          { \if_false: { \fi: } \__regex_branch:n { \if_false: } \fi: }
      }
  }
\cs_new_protected_nopar:cpn { __regex_compile_): }
  {
    \__regex_if_in_class:TF { \__regex_compile_raw:N ) }
      { \__regex_compile_group_end: }
  }
\cs_new_protected_nopar:cpn { __regex_compile_special_group_::w }
  { \__regex_compile_group_begin:N \__regex_group_no_capture:nnnN }
\cs_new_protected_nopar:cpn { __regex_compile_special_group_|:w }
  { \__regex_compile_group_begin:N \__regex_group_resetting:nnnN }
\cs_new_protected:Npn \__regex_compile_special_group_i:w #1#2
  {
    \str_if_eq:nnTF { #1 #2 } { \__regex_compile_special:N ) }
      {
        \cs_set_nopar:Npn \__regex_item_equal:n  { \__regex_item_caseless_equal:n }
        \cs_set_nopar:Npn \__regex_item_range:nn { \__regex_item_caseless_range:nn }
      }
      {
        \__msg_kernel_warning:nnx { regex } { unknown-option } { (?i #2 }
        \__regex_compile_raw:N (
        \__regex_compile_raw:N ?
        \__regex_compile_raw:N i
        #1 #2
      }
  }
\cs_new_protected_nopar:cpn { __regex_compile_special_group_-:w } #1#2#3#4
  {
    \str_if_eq:nnTF { #1 #2 #3 #4 }
      { \__regex_compile_raw:N i \__regex_compile_special:N ) }
      {
        \cs_set_nopar:Npn \__regex_item_equal:n  { \__regex_item_caseful_equal:n }
        \cs_set_nopar:Npn \__regex_item_range:nn { \__regex_item_caseful_range:nn }
      }
      {
        \__msg_kernel_warning:nnx { regex } { unknown-option } { (?-#2#4 }
        \__regex_compile_raw:N (
        \__regex_compile_raw:N ?
        \__regex_compile_raw:N -
        #1 #2 #3 #4
      }
  }
\cs_new_protected:cpn { __regex_compile_/c: }
  { \__regex_chk_c_allowed:T { \__regex_compile_c_test:NN } }
\cs_new_protected:Npn \__regex_compile_c_test:NN #1#2
  {
    \token_if_eq_meaning:NNTF #1 \__regex_compile_raw:N
      {
        \int_if_exist:cTF { c__regex_catcode_#2_int }
          {
            \int_set_eq:Nc \l__regex_catcodes_int { c__regex_catcode_#2_int }
            \l__regex_mode_int
              = \if_case:w \l__regex_mode_int \c_two \else: \c_six \fi:
          }
      }
      { \cs_if_exist_use:cF { __regex_compile_c_#2:w } }
          {
            \__msg_kernel_error:nnx { regex } { c-missing-category } {#2}
            #1 #2
          }
  }
\cs_new_protected:cpn { __regex_compile_c_[:w } #1#2
  {
    \l__regex_mode_int
      = \if_case:w \l__regex_mode_int \c_two \else: \c_six \fi:
    \int_zero:N \l__regex_catcodes_int
    \str_if_eq:nnTF { #1 #2 } { \__regex_compile_special:N ^ }
      {
        \bool_set_false:N \l__regex_catcodes_bool
        \__regex_compile_c_lbrack_loop:NN
      }
      {
        \bool_set_true:N \l__regex_catcodes_bool
        \__regex_compile_c_lbrack_loop:NN
        #1 #2
      }
  }
\cs_new_protected:Npn \__regex_compile_c_lbrack_loop:NN #1#2
  {
    \token_if_eq_meaning:NNTF #1 \__regex_compile_raw:N
      {
        \int_if_exist:cTF { c__regex_catcode_#2_int }
          {
            \exp_args:Nc \__regex_compile_c_lbrack_add:N
              { c__regex_catcode_#2_int }
            \__regex_compile_c_lbrack_loop:NN
          }
      }
      {
        \token_if_eq_charcode:NNTF #2 ]
          { \__regex_compile_c_lbrack_end: }
      }
          {
            \__msg_kernel_error:nnx { regex } { c-missing-rbrack } {#2}
            \__regex_compile_c_lbrack_end:
            #1 #2
          }
  }
\cs_new_protected:Npn \__regex_compile_c_lbrack_add:N #1
  {
    \if_int_odd:w \__int_eval:w \l__regex_catcodes_int / #1 \__int_eval_end:
    \else:
      \tex_advance:D \l__regex_catcodes_int #1
    \fi:
  }
\cs_new_protected_nopar:Npn \__regex_compile_c_lbrack_end:
  {
    \if_meaning:w \c_false_bool \l__regex_catcodes_bool
      \int_set:Nn \l__regex_catcodes_int
        { \c__regex_all_catcodes_int - \l__regex_catcodes_int }
    \fi:
  }
\cs_new_protected_nopar:cpn { __regex_compile_c_ \c_left_brace_str :w }
  {
    \__regex_compile:w
      \__regex_disable_submatches:
      \l__regex_mode_int
        = - \if_case:w \l__regex_mode_int \c_two \else: \c_six \fi:
  }
\cs_new_protected:cpn { __regex_compile_ \c_right_brace_str : }
  {
    \__regex_if_in_cs:TF
      {
        \__regex_compile_end:
        \__regex_compile_one:x
          { \__regex_item_cs:n { \exp_not:o \l__regex_internal_regex } }
      }
      { \exp_after:wN \__regex_compile_raw:N \c_right_brace_str }
  }
\cs_new_protected:cpn { __regex_compile_/u: } #1#2
  {
    \__regex_if_in_class_or_catcode:TF
      { \__regex_compile_raw_error:N u #1 #2 }
      {
        \str_if_eq_x:nnTF {#1#2} { \__regex_compile_special:N \c_left_brace_str }
          {
            \tl_set:Nx \l__regex_internal_a_tl { \if_false: } \fi:
            \__regex_compile_u_loop:NN
          }
          {
            \__msg_kernel_error:nn { regex } { u-missing-lbrace }
            \__regex_compile_raw:N u #1 #2
          }
      }
  }
\cs_new:Npn \__regex_compile_u_loop:NN #1#2
  {
    \token_if_eq_meaning:NNTF #1 \__regex_compile_raw:N
      { #2 \__regex_compile_u_loop:NN }
      {
        \token_if_eq_meaning:NNTF #1 \__regex_compile_special:N
          {
            \exp_after:wN \token_if_eq_charcode:NNTF \c_right_brace_str #2
              { \if_false: { \fi: } \__regex_compile_u_end: }
              { #2 \__regex_compile_u_loop:NN }
          }
          {
            \if_false: { \fi: }
            \__msg_kernel_error:nnx { regex } { u-missing-rbrace } {#2}
            \__regex_compile_u_end:
            #1 #2
          }
      }
  }
\cs_new_protected:Npn \__regex_compile_u_end:
  {
    \tl_set:Nv \l__regex_internal_a_tl { \l__regex_internal_a_tl }
    \if_int_compare:w \l__regex_mode_int = \c_zero
      \__regex_compile_u_not_cs:
    \else:
      \__regex_compile_u_in_cs:
    \fi:
  }
\cs_new_protected:Npn \__regex_compile_u_in_cs:
  {
    \exp_args:NNo \__str_gset_other:Nn \g__regex_internal_tl
      { \l__regex_internal_a_tl }
    \__tl_build_one:x
      {
        \tl_map_function:NN \g__regex_internal_tl
          \__regex_compile_u_in_cs_aux:n
      }
  }
\cs_new:Npn \__regex_compile_u_in_cs_aux:n #1
  {
    \__regex_class:NnnnN \c_true_bool
      { \__regex_item_caseful_equal:n { \__int_value:w `#1 } }
      { 1 } { 0 } \c_false_bool
  }
\cs_new_protected:Npn \__regex_compile_u_not_cs:
  {
    \exp_args:No \__tl_analysis_map_inline:nn { \l__regex_internal_a_tl }
      {
        \__tl_build_one:n
          {
            \__regex_class:NnnnN \c_true_bool
              {
                \if_int_compare:w "##2 = \c_zero
                  \__regex_item_exact_cs:c { \exp_after:wN \cs_to_str:N ##1 }
                \else:
                  \__regex_item_exact:nn { \__int_value:w "##2 } { ##3 }
                \fi:
              }
              { 1 } { 0 } \c_false_bool
          }
      }
  }
\cs_new_protected_nopar:cpn { __regex_compile_/K: }
  {
    \int_compare:nNnTF \l__regex_mode_int = \c_zero
      { \__tl_build_one:n { \__regex_command_K: } }
      { \__regex_compile_raw_error:N K }
  }
\cs_new_protected:Npn \__regex_show:Nx #1#2
  {
    \__tl_build:Nw \l__regex_internal_a_tl
      \cs_set_protected_nopar:Npn \__regex_branch:n
        {
          \seq_pop_right:NN \l__regex_show_prefix_seq \l__regex_internal_a_tl
          \__regex_show_one:n { +-branch }
          \seq_put_right:No \l__regex_show_prefix_seq \l__regex_internal_a_tl
          \use:n
        }
      \cs_set_protected_nopar:Npn \__regex_group:nnnN
        { \__regex_show_group_aux:nnnnN { } }
      \cs_set_protected_nopar:Npn \__regex_group_no_capture:nnnN
        { \__regex_show_group_aux:nnnnN { ~(no~capture) } }
      \cs_set_protected_nopar:Npn \__regex_group_resetting:nnnN
        { \__regex_show_group_aux:nnnnN { ~(resetting) } }
      \cs_set_eq:NN \__regex_class:NnnnN \__regex_show_class:NnnnN
      \cs_set_protected_nopar:Npn \__regex_command_K:
        { \__regex_show_one:n { reset~match~start~(\iow_char:N\\K) } }
      \cs_set_protected:Npn \__regex_assertion:Nn ##1##2
        { \__regex_show_one:n { \bool_if:NF ##1 { negative~ } assertion:~##2 } }
      \cs_set_nopar:Npn \__regex_b_test: { word~boundary }
      \cs_set_eq:NN \__regex_anchor:N \__regex_show_anchor_to_str:N
      \cs_set_protected:Npn \__regex_item_caseful_equal:n ##1
        { \__regex_show_one:n { char~code~\int_eval:n{##1} } }
      \cs_set_protected:Npn \__regex_item_caseful_range:nn ##1##2
        { \__regex_show_one:n { range~[\int_eval:n{##1}, \int_eval:n{##2}] } }
      \cs_set_protected:Npn \__regex_item_caseless_equal:n ##1
        { \__regex_show_one:n { char~code~\int_eval:n{##1}~(caseless) } }
      \cs_set_protected:Npn \__regex_item_caseless_range:nn ##1##2
        {
          \__regex_show_one:n
            { Range~[\int_eval:n{##1}, \int_eval:n{##2}]~(caseless) }
        }
      \cs_set_protected:Npn \__regex_item_catcode:nT
        { \__regex_show_item_catcode:NnT \c_true_bool }
      \cs_set_protected:Npn \__regex_item_catcode_reverse:nT
        { \__regex_show_item_catcode:NnT \c_false_bool }
      \cs_set_protected:Npn \__regex_item_reverse:n
        { \__regex_show_scope:nn { Reversed~match } }
      \cs_set_protected:Npn \__regex_item_exact:nn ##1##2
        { \__regex_show_one:n { char~##2,~catcode~##1 } }
      \cs_set_protected:Npn \__regex_item_exact_cs:c ##1
        { \__regex_show_one:n { control~sequence~\iow_char:N\\##1 } }
      \cs_set_protected:Npn \__regex_item_cs:n
        { \__regex_show_scope:nn { control~sequence } }
      \cs_set:cpn { __regex_prop_.: } { \__regex_show_one:n { any~token } }
      \seq_clear:N \l__regex_show_prefix_seq
      \__regex_show_push:n { ~ }
      #1
    \__tl_build_end:
    \__msg_show_variable:n { >~Compiled~regex~#2: \l__regex_internal_a_tl }
  }
\cs_new_protected:Npn \__regex_show_one:n #1
  {
    \int_incr:N \l__regex_show_lines_int
    \__tl_build_one:x
      {
        \exp_not:N \\
        \seq_map_function:NN \l__regex_show_prefix_seq \use:n
        #1
      }
  }
\cs_new_protected:Npn \__regex_show_push:n #1
  { \seq_put_right:Nx \l__regex_show_prefix_seq { #1 ~ } }
\cs_new_protected:Npn \__regex_show_pop:
  { \seq_pop_right:NN \l__regex_show_prefix_seq \l__regex_internal_a_tl }
\cs_new_protected:Npn \__regex_show_scope:nn #1#2
  {
    \__regex_show_one:n {#1}
    \__regex_show_push:n { ~ }
    #2
    \__regex_show_pop:
  }
\cs_new_protected:Npn \__regex_show_group_aux:nnnnN #1#2#3#4#5
  {
    \__regex_show_one:n { ,-group~begin #1 }
    \__regex_show_push:n { | }
    \use_ii:nn #2
    \__regex_show_pop:
    \__regex_show_one:n
      { `-group~end \__regex_msg_repeated:nnN {#3} {#4} #5 }
  }
\cs_set:Npn \__regex_show_class:NnnnN #1#2#3#4#5
  {
    \__tl_build:Nw \l__regex_internal_a_tl
      \int_zero:N \l__regex_show_lines_int
      \__regex_show_push:n {~}
      #2
      \exp_last_unbraced:Nf
    \int_case:nnF { \l__regex_show_lines_int }
      {
        {0}
          {
            \__tl_build_end:
            \__regex_show_one:n { \bool_if:NTF #1 { Fail } { Pass } }
          }
        {1}
          {
            \__tl_build_end:
            \bool_if:NTF #1
              {
                #2
                \__tl_build_one:n { \__regex_msg_repeated:nnN {#3} {#4} #5 }
              }
              {
                \__regex_show_one:n
                  { Don't~match~\__regex_msg_repeated:nnN {#3} {#4} #5 }
                \__tl_build_one:o \l__regex_internal_a_tl
              }
          }
      }
      {
        \__tl_build_end:
        \__regex_show_one:n
          {
            \bool_if:NTF #1 { M } { Don't~m } atch
            \__regex_msg_repeated:nnN {#3} {#4} #5
          }
        \__tl_build_one:o \l__regex_internal_a_tl
      }
  }
\cs_new:Npn \__regex_show_anchor_to_str:N #1
  {
    anchor~at~
    \str_case:nnF { #1 }
      {
        { \l__regex_min_pos_int   } { start~(\iow_char:N\\A) }
        { \l__regex_start_pos_int } { start~of~match~(\iow_char:N\\G) }
        { \l__regex_max_pos_int   } { end~(\iow_char:N\\Z) }
      }
      { <error:~'#1'~not~recognized> }
  }
\cs_new_protected:Npn \__regex_show_item_catcode:NnT #1#2
  {
    \seq_set_split:Nnn \l__regex_internal_seq { } { CBEMTPUDSLOA }
    \seq_set_filter:NNn \l__regex_internal_seq \l__regex_internal_seq
      { \int_if_odd_p:n { #2 / \int_use:c { c__regex_catcode_##1_int } } }
    \__regex_show_scope:nn
      {
        categories~
        \seq_map_function:NN \l__regex_internal_seq \use:n
        , ~
        \bool_if:NF #1 { negative~ } class
      }
  }
\int_new:N  \l__regex_min_state_int
\int_new:N  \l__regex_max_state_int
\int_new:N  \l__regex_left_state_int
\int_new:N  \l__regex_right_state_int
\seq_new:N  \l__regex_left_state_seq
\seq_new:N  \l__regex_right_state_seq
\int_new:N  \l__regex_capturing_group_int
\cs_new_protected:Npn \__regex_build:n #1
  {
    \__regex_compile:n {#1}
    \__regex_build:N \l__regex_internal_regex
  }
\cs_new_protected:Npn \__regex_build:N #1
  {
    \int_set:Nn \tex_escapechar:D { 92 }
    \int_zero:N \l__regex_capturing_group_int
    \int_set_eq:NN \l__regex_max_state_int \l__regex_min_state_int
    \__regex_build_new_state:
    \__regex_build_new_state:
    \__regex_toks_put_right:Nn \l__regex_left_state_int
      { \__regex_action_start_wildcard: }
    \__regex_group:nnnN {#1} { 1 } { 0 } \c_false_bool
    \__regex_toks_put_right:Nn \l__regex_right_state_int
      { \__regex_action_success: }
  }
\cs_new_protected:Npn \__regex_build_for_cs:n #1
  {
    \int_set_eq:NN \l__regex_max_state_int \l__regex_min_state_int
    \__regex_build_new_state:
    \__regex_build_new_state:
    \__regex_push_lr_states:
    #1
    \__regex_pop_lr_states:
    \__regex_toks_put_right:Nn \l__regex_right_state_int
      {
        \if_int_compare:w \l__regex_current_pos_int = \l__regex_max_pos_int
          \exp_after:wN \__regex_action_success:
        \fi:
      }
  }
\cs_new_protected_nopar:Npn \__regex_push_lr_states:
  {
    \seq_push:No \l__regex_left_state_seq
      { \int_use:N \l__regex_left_state_int }
    \seq_push:No \l__regex_right_state_seq
      { \int_use:N \l__regex_right_state_int }
  }
\cs_new_protected_nopar:Npn \__regex_pop_lr_states:
  {
    \seq_pop:NN \l__regex_left_state_seq  \l__regex_internal_a_tl
    \int_set:Nn \l__regex_left_state_int  \l__regex_internal_a_tl
    \seq_pop:NN \l__regex_right_state_seq \l__regex_internal_a_tl
    \int_set:Nn \l__regex_right_state_int \l__regex_internal_a_tl
  }
\cs_new_protected:Npn \__regex_toks_put_left:Nx #1#2
  {
    \cs_set_nopar:Npx \__regex_tmp:w { #2 }
    \tex_toks:D #1 \exp_after:wN \exp_after:wN \exp_after:wN
      { \exp_after:wN \__regex_tmp:w \tex_the:D \tex_toks:D #1 }
  }
\cs_new_protected:Npn \__regex_toks_put_right:Nx #1#2
  {
    \cs_set_nopar:Npx \__regex_tmp:w {#2}
    \tex_toks:D #1 \exp_after:wN
      { \tex_the:D \tex_toks:D \exp_after:wN #1 \__regex_tmp:w }
  }
\cs_new_protected:Npn \__regex_toks_put_right:Nn #1#2
  { \tex_toks:D #1 \exp_after:wN { \tex_the:D \tex_toks:D #1 #2 } }
\cs_new_protected:Npn \__regex_build_transition_left:NNN #1#2#3
  { \__regex_toks_put_left:Nx  #2 { #1 { \int_eval:n { #3 - #2 } } } }
\cs_new_protected:Npn \__regex_build_transition_right:nNn #1#2#3
  { \__regex_toks_put_right:Nx #2 { #1 { \int_eval:n { #3 - #2 } } } }
\cs_new_protected_nopar:Npn \__regex_build_new_state:
  {
    \tex_toks:D \l__regex_max_state_int { }
    \int_set_eq:NN \l__regex_left_state_int \l__regex_right_state_int
    \int_set_eq:NN \l__regex_right_state_int \l__regex_max_state_int
    \int_incr:N \l__regex_max_state_int
  }
\cs_new_protected:Npn \__regex_build_transitions_lazyness:NNNNN #1#2#3#4#5
  {
    \__regex_build_new_state:
    \__regex_toks_put_right:Nx \l__regex_left_state_int
      {
        \if_meaning:w \c_true_bool #1
          #2 { \int_eval:n { #3 - \l__regex_left_state_int } }
          #4 { \int_eval:n { #5 - \l__regex_left_state_int } }
        \else:
          #4 { \int_eval:n { #5 - \l__regex_left_state_int } }
          #2 { \int_eval:n { #3 - \l__regex_left_state_int } }
        \fi:
      }
  }
\cs_new_protected:Npn \__regex_class:NnnnN #1#2#3#4#5
  {
    \cs_set_nopar:Npx \__regex_tests_action_cost:n ##1
      {
        \exp_not:n { \exp_not:n {#2} }
        \bool_if:NTF #1
          { \__regex_break_point:TF { \__regex_action_cost:n {##1} } { } }
          { \__regex_break_point:TF { } { \__regex_action_cost:n {##1} } }
      }
    \if_case:w - #4 \exp_stop_f:
           \__regex_class_repeat:n   {#3}
    \or:   \__regex_class_repeat:nN  {#3}      #5
    \else: \__regex_class_repeat:nnN {#3} {#4} #5
    \fi:
  }
\cs_new:Npn \__regex_tests_action_cost:n { \__regex_action_cost:n }
\cs_new_protected:Npn \__regex_class_repeat:n #1
  {
    \prg_replicate:nn {#1}
      {
        \__regex_build_new_state:
        \__regex_build_transition_right:nNn \__regex_tests_action_cost:n
          \l__regex_left_state_int \l__regex_right_state_int
      }
  }
\cs_new_protected:Npn \__regex_class_repeat:nN #1#2
  {
    \if_int_compare:w #1 = \c_zero
      \__regex_build_transitions_lazyness:NNNNN #2
        \__regex_action_free:n       \l__regex_right_state_int
        \__regex_tests_action_cost:n \l__regex_left_state_int
    \else:
      \__regex_class_repeat:n {#1}
      \int_set_eq:NN \l__regex_internal_a_int \l__regex_left_state_int
      \__regex_build_transitions_lazyness:NNNNN #2
        \__regex_action_free:n \l__regex_right_state_int
        \__regex_action_free:n \l__regex_internal_a_int
    \fi:
  }
\cs_new_protected:Npn \__regex_class_repeat:nnN #1#2#3
  {
    \__regex_class_repeat:n {#1}
    \int_set:Nn \l__regex_internal_a_int
      { \l__regex_max_state_int + #2 - \c_one }
    \prg_replicate:nn { #2 }
      {
        \__regex_build_transitions_lazyness:NNNNN #3
          \__regex_action_free:n       \l__regex_internal_a_int
          \__regex_tests_action_cost:n \l__regex_right_state_int
      }
  }
\cs_new_protected:Npn \__regex_group_aux:nnnnN #1#2#3#4#5
  {
      \if_int_compare:w #3 = \c_zero
        \__regex_build_new_state:
        \__regex_build_transition_right:nNn \__regex_action_free_group:n
          \l__regex_left_state_int \l__regex_right_state_int
      \fi:
      \__regex_build_new_state:
      \__regex_push_lr_states:
      #2
      \__regex_pop_lr_states:
      \if_case:w - #4 \exp_stop_f:
             \__regex_group_repeat:nn   {#1} {#3}
      \or:   \__regex_group_repeat:nnN  {#1} {#3}      #5
      \else: \__regex_group_repeat:nnnN {#1} {#3} {#4} #5
      \fi:
  }
\cs_new_protected:Npn \__regex_group:nnnN #1
  {
    \exp_args:No \__regex_group_aux:nnnnN
      { \int_use:N \l__regex_capturing_group_int }
      {
        \int_incr:N \l__regex_capturing_group_int
        #1
      }
  }
\cs_new_protected_nopar:Npn \__regex_group_no_capture:nnnN
  { \__regex_group_aux:nnnnN { -1 } }
\cs_new_protected:Npn \__regex_group_resetting:nnnN #1
  {
    \__regex_group_aux:nnnnN { -1 }
      {
        \exp_args:Noo \__regex_group_resetting_loop:nnNn
          { \int_use:N \l__regex_capturing_group_int }
          { \int_use:N \l__regex_capturing_group_int }
          #1
          { ?? \__prg_break:n } { }
        \__prg_break_point:
      }
  }
\cs_new_protected:Npn \__regex_group_resetting_loop:nnNn #1#2#3#4
  {
    \use_none:nn #3 { \int_set:Nn \l__regex_capturing_group_int {#1} }
    \int_set:Nn \l__regex_capturing_group_int {#2}
    #3 {#4}
    \exp_args:Nf \__regex_group_resetting_loop:nnNn
      { \int_max:nn {#1} { \l__regex_capturing_group_int } }
      {#2}
  }
\cs_new_protected:Npn \__regex_branch:n #1
  {
    \__regex_build_new_state:
    \seq_get:NN \l__regex_left_state_seq \l__regex_internal_a_tl
    \int_set:Nn \l__regex_left_state_int \l__regex_internal_a_tl
    \__regex_build_transition_right:nNn \__regex_action_free:n
      \l__regex_left_state_int \l__regex_right_state_int
    #1
    \seq_get:NN \l__regex_right_state_seq \l__regex_internal_a_tl
    \__regex_build_transition_right:nNn \__regex_action_free:n
      \l__regex_right_state_int \l__regex_internal_a_tl
  }
\cs_new_protected:Npn \__regex_group_repeat:nn #1#2
  {
    \if_int_compare:w #2 = \c_zero
      \int_set:Nn \l__regex_max_state_int
        { \l__regex_left_state_int - \c_one }
      \__regex_build_new_state:
    \else:
      \__regex_group_repeat_aux:n {#2}
      \__regex_group_submatches:nNN {#1}
        \l__regex_internal_a_int \l__regex_right_state_int
      \__regex_build_new_state:
    \fi:
  }
\cs_new_protected:Npn \__regex_group_submatches:nNN #1#2#3
  {
    \if_int_compare:w #1 > \c_minus_one
      \__regex_toks_put_left:Nx #2 { \__regex_action_submatch:n { #1 < } }
      \__regex_toks_put_left:Nx #3 { \__regex_action_submatch:n { #1 > } }
    \fi:
  }
\cs_new_protected:Npn \__regex_group_repeat_aux:n #1
  {
    \__regex_build_transition_right:nNn \__regex_action_free:n
      \l__regex_right_state_int \l__regex_max_state_int
    \int_set_eq:NN \l__regex_internal_a_int \l__regex_left_state_int
    \int_set_eq:NN \l__regex_internal_b_int \l__regex_max_state_int
    \if_int_compare:w \__int_eval:w #1 > \c_one
      \int_set:Nn \l__regex_internal_c_int
        {
          ( #1 - \c_one )
          * ( \l__regex_internal_b_int - \l__regex_internal_a_int )
        }
      \tex_advance:D \l__regex_right_state_int \l__regex_internal_c_int
      \tex_advance:D \l__regex_max_state_int   \l__regex_internal_c_int
      \prg_replicate:nn \l__regex_internal_c_int
        {
          \tex_toks:D \l__regex_internal_b_int
            = \tex_toks:D \l__regex_internal_a_int
          \tex_advance:D \l__regex_internal_a_int \c_one
          \tex_advance:D \l__regex_internal_b_int \c_one
        }
    \fi:
  }
\cs_new_protected:Npn \__regex_group_repeat:nnN #1#2#3
  {
    \if_int_compare:w #2 = \c_zero
      \__regex_group_submatches:nNN {#1}
        \l__regex_left_state_int \l__regex_right_state_int
      \int_set:Nn \l__regex_internal_a_int
        { \l__regex_left_state_int - \c_one }
      \__regex_build_transition_right:nNn \__regex_action_free:n
        \l__regex_right_state_int \l__regex_internal_a_int
      \__regex_build_new_state:
      \if_meaning:w \c_true_bool #3
        \__regex_build_transition_left:NNN \__regex_action_free:n
          \l__regex_internal_a_int \l__regex_right_state_int
      \else:
        \__regex_build_transition_right:nNn \__regex_action_free:n
          \l__regex_internal_a_int \l__regex_right_state_int
      \fi:
    \else:
      \__regex_group_repeat_aux:n {#2}
      \__regex_group_submatches:nNN {#1}
        \l__regex_internal_a_int \l__regex_right_state_int
      \if_meaning:w \c_true_bool #3
        \__regex_build_transition_right:nNn \__regex_action_free_group:n
          \l__regex_right_state_int \l__regex_internal_a_int
      \else:
        \__regex_build_transition_left:NNN \__regex_action_free_group:n
          \l__regex_right_state_int \l__regex_internal_a_int
      \fi:
      \__regex_build_new_state:
    \fi:
  }
\cs_new_protected:Npn \__regex_group_repeat:nnnN #1#2#3#4
  {
    \__regex_group_submatches:nNN {#1}
      \l__regex_left_state_int \l__regex_right_state_int
    \__regex_group_repeat_aux:n { #2 + #3 }
    \if_meaning:w \c_true_bool #4
      \int_set_eq:NN \l__regex_left_state_int \l__regex_max_state_int
      \prg_replicate:nn { #3 }
        {
          \int_sub:Nn \l__regex_left_state_int
            { \l__regex_internal_b_int - \l__regex_internal_a_int }
          \__regex_build_transition_left:NNN \__regex_action_free:n
            \l__regex_left_state_int \l__regex_max_state_int
        }
    \else:
      \prg_replicate:nn { #3 - \c_one }
        {
          \int_sub:Nn \l__regex_right_state_int
            { \l__regex_internal_b_int - \l__regex_internal_a_int }
          \__regex_build_transition_right:nNn \__regex_action_free:n
            \l__regex_right_state_int \l__regex_max_state_int
        }
      \if_int_compare:w #2 = \c_zero
        \int_set:Nn \l__regex_right_state_int
          { \l__regex_left_state_int - \c_one }
      \else:
        \int_sub:Nn \l__regex_right_state_int
          { \l__regex_internal_b_int - \l__regex_internal_a_int }
      \fi:
      \__regex_build_transition_right:nNn \__regex_action_free:n
        \l__regex_right_state_int \l__regex_max_state_int
    \fi:
    \__regex_build_new_state:
  }
\cs_new_protected:Npn \__regex_assertion:Nn #1#2
  {
    \__regex_build_new_state:
    \__regex_toks_put_right:Nx \l__regex_left_state_int
      {
        \exp_not:n {#2}
        \__regex_break_point:TF
          \bool_if:NF #1 { { } }
          {
            \__regex_action_free:n
              {
                \int_eval:n
                  { \l__regex_right_state_int - \l__regex_left_state_int }
              }
          }
          \bool_if:NT #1 { { } }
      }
  }
\cs_new_protected:Npn \__regex_anchor:N #1
  {
    \if_int_compare:w #1 = \l__regex_current_pos_int
      \exp_after:wN \__regex_break_true:w
    \fi:
  }
\cs_new_protected_nopar:Npn \__regex_b_test:
  {
    \group_begin:
      \int_set_eq:NN \l__regex_current_char_int \l__regex_last_char_int
      \__regex_prop_w:
      \__regex_break_point:TF
        { \group_end: \__regex_item_reverse:n \__regex_prop_w: }
        { \group_end: \__regex_prop_w: }
  }
\cs_new_protected_nopar:Npn \__regex_command_K:
  {
    \__regex_build_new_state:
    \__regex_toks_put_right:Nx \l__regex_left_state_int
      {
        \__regex_action_submatch:n { 0< }
        \bool_set_true:N \l__regex_fresh_thread_bool
        \__regex_action_free:n
          { \int_eval:n { \l__regex_right_state_int - \l__regex_left_state_int } }
        \bool_set_false:N \l__regex_fresh_thread_bool
      }
  }
\int_new:N \l__regex_min_pos_int
\int_new:N \l__regex_max_pos_int
\int_new:N \l__regex_current_pos_int
\int_new:N \l__regex_start_pos_int
\int_new:N \l__regex_success_pos_int
\int_new:N \l__regex_current_char_int
\int_new:N \l__regex_current_catcode_int
\int_new:N \l__regex_last_char_int
\int_new:N \l__regex_case_changed_char_int
\int_new:N \l__regex_current_state_int
\prop_new:N \l__regex_current_submatches_prop
\prop_new:N \l__regex_success_submatches_prop
\int_new:N \l__regex_step_int
\int_new:N \l__regex_min_active_int
\int_new:N \l__regex_max_active_int
\tl_new:N \l__regex_every_match_tl
\bool_new:N \l__regex_fresh_thread_bool
\bool_new:N \l__regex_empty_success_bool
\cs_new_eq:NN \__regex_if_two_empty_matches:F \use:n
\bool_new:N \g__regex_success_bool
\bool_new:N \l__regex_saved_success_bool
\bool_new:N \l__regex_match_success_bool
\cs_new_protected:Npn \__regex_match:n #1
  {
    \int_zero:N \l__regex_balance_int
    \int_set:Nn \l__regex_current_pos_int { \c_two * \l__regex_max_state_int }
    \__regex_query_set:nnn { } { -1 } { -2 }
    \int_set_eq:NN \l__regex_min_pos_int \l__regex_current_pos_int
    \__tl_analysis_map_inline:nn {#1}
      { \__regex_query_set:nnn {##1} {"##2} {##3} }
    \int_set_eq:NN \l__regex_max_pos_int \l__regex_current_pos_int
    \__regex_query_set:nnn { } { -1 } { -2 }
    \bool_gset_false:N \g__regex_success_bool
    \int_step_inline:nnnn
      \l__regex_min_state_int \c_one { \l__regex_max_state_int - \c_one }
      { \tex_dimen:D ##1 \c_one sp \scan_stop: }
    \int_set_eq:NN \l__regex_min_active_int \l__regex_max_state_int
    \int_set_eq:NN \l__regex_step_int \c_zero
    \int_set_eq:NN \l__regex_success_pos_int \l__regex_min_pos_int
    \int_set:Nn \l__regex_submatch_int
      { \c_two * \l__regex_max_state_int }
    \bool_set_false:N \l__regex_empty_success_bool
    \__regex_match_once:
  }
\cs_new_protected_nopar:Npn \__regex_match_once:
  {
    \if_meaning:w \c_true_bool \l__regex_empty_success_bool
      \cs_set_nopar:Npn \__regex_if_two_empty_matches:F
        { \int_compare:nNnF \l__regex_start_pos_int = \l__regex_current_pos_int }
    \else:
      \cs_set_eq:NN \__regex_if_two_empty_matches:F \use:n
    \fi:
    \int_set_eq:NN \l__regex_start_pos_int \l__regex_success_pos_int
    \bool_set_false:N \l__regex_match_success_bool
    \prop_clear:N \l__regex_current_submatches_prop
    \int_set_eq:NN \l__regex_max_active_int \l__regex_min_active_int
    \__regex_store_state:n { \l__regex_min_state_int }
    \int_set:Nn \l__regex_current_pos_int
      { \l__regex_start_pos_int - \c_one }
    \__regex_query_get:
    \__regex_match_loop:
    \l__regex_every_match_tl
  }
\cs_new_protected_nopar:Npn \__regex_single_match:
  {
    \tl_set:Nn \l__regex_every_match_tl
      { \bool_gset_eq:NN \g__regex_success_bool \l__regex_match_success_bool }
  }
\cs_new_protected:Npn \__regex_multi_match:n #1
  {
    \tl_set:Nn \l__regex_every_match_tl
      {
        \if_meaning:w \c_true_bool \l__regex_match_success_bool
          \bool_gset_true:N \g__regex_success_bool
          #1
          \exp_after:wN \__regex_match_once:
        \fi:
      }
  }
\cs_new_protected_nopar:Npn \__regex_match_loop:
  {
    \tex_advance:D \l__regex_step_int \c_two
    \int_incr:N \l__regex_current_pos_int
    \int_set_eq:NN \l__regex_last_char_int \l__regex_current_char_int
    \int_set_eq:NN \l__regex_case_changed_char_int \c_max_int
    \__regex_query_get:
    \use:x
      {
        \int_set_eq:NN \l__regex_max_active_int \l__regex_min_active_int
        \exp_after:wN \__regex_match_one_active:w
          \int_use:N \l__regex_min_active_int ;
      }
    \__prg_break_point:
    \bool_set_false:N \l__regex_fresh_thread_bool %^^A was arg of break_point:n
    \if_int_compare:w \l__regex_max_active_int > \l__regex_min_active_int
      \if_int_compare:w \l__regex_current_pos_int < \l__regex_max_pos_int
        \exp_after:wN \exp_after:wN \exp_after:wN \__regex_match_loop:
      \fi:
    \fi:
  }
\cs_new:Npn \__regex_match_one_active:w #1;
  {
    \if_int_compare:w #1 < \l__regex_max_active_int
      \__regex_use_state_and_submatches:nn
        { \__int_value:w \tex_skip:D #1 }
        { \tex_the:D \tex_toks:D #1 }
      \exp_after:wN \__regex_match_one_active:w
        \int_use:N \__int_eval:w #1 + \c_one \exp_after:wN ;
    \fi:
  }
\cs_new_protected:Npn \__regex_query_set:nnn #1#2#3
  {
    \tex_muskip:D \l__regex_current_pos_int
      = \etex_gluetomu:D
        #3 sp
        plus #2 sp
        minus \l__regex_balance_int sp
      \scan_stop:
    \tex_toks:D \l__regex_current_pos_int {#1}
    \int_incr:N \l__regex_current_pos_int
    \if_case:w #2 \exp_stop_f:
    \or: \int_incr:N \l__regex_balance_int
    \or: \int_decr:N \l__regex_balance_int
    \fi:
  }
\cs_new_protected_nopar:Npn \__regex_query_get:
  {
    \l__regex_current_char_int
      = \etex_mutoglue:D \tex_muskip:D \l__regex_current_pos_int
    \l__regex_current_catcode_int = \etex_gluestretch:D
      \etex_mutoglue:D \tex_muskip:D \l__regex_current_pos_int
  }
\cs_new_protected_nopar:Npn \__regex_use_state:
  {
    \tex_dimen:D \l__regex_current_state_int
      = \l__regex_step_int sp \scan_stop:
    \tex_the:D \tex_toks:D \l__regex_current_state_int
    \tex_dimen:D \l__regex_current_state_int
      = \__int_eval:w \l__regex_step_int + \c_one \__int_eval_end: sp \scan_stop:
  }
\cs_new_protected:Npn \__regex_use_state_and_submatches:nn #1 #2
  {
    \int_set:Nn \l__regex_current_state_int {#1}
    \if_int_compare:w \tex_dimen:D \l__regex_current_state_int
                      < \l__regex_step_int
      \tl_set:Nn \l__regex_current_submatches_prop {#2}
      \exp_after:wN \__regex_use_state:
    \fi:
    \scan_stop:
  }
\cs_new_protected_nopar:Npn \__regex_action_start_wildcard:
  {
    \bool_set_true:N \l__regex_fresh_thread_bool
    \__regex_action_free:n {1}
    \bool_set_false:N \l__regex_fresh_thread_bool
    \__regex_action_cost:n {0}
  }
\cs_new_protected_nopar:Npn \__regex_action_free:n
  { \__regex_action_free_aux:nn { > \l__regex_step_int \else: } }
\cs_new_protected_nopar:Npn \__regex_action_free_group:n
  { \__regex_action_free_aux:nn { < \l__regex_step_int } }
\cs_new_protected:Npn \__regex_action_free_aux:nn #1#2
  {
    \use:x
      {
        \int_add:Nn \l__regex_current_state_int {#2}
        \exp_not:n
          {
            \if_int_compare:w \tex_dimen:D \l__regex_current_state_int #1
              \exp_after:wN \__regex_use_state:
            \fi:
          }
        \int_set:Nn \l__regex_current_state_int
          { \int_use:N \l__regex_current_state_int }
        \tl_set:Nn \exp_not:N \l__regex_current_submatches_prop
          { \exp_not:o \l__regex_current_submatches_prop }
      }
  }
\cs_new_protected:Npn \__regex_action_cost:n #1
  {
    \exp_args:No \__regex_store_state:n
      { \int_use:N \__int_eval:w \l__regex_current_state_int + #1 }
  }
\cs_new_protected:Npn \__regex_store_state:n #1
  {
    \__regex_store_submatches:
    \tex_skip:D \l__regex_max_active_int = #1 sp \scan_stop:
    \int_incr:N \l__regex_max_active_int
  }
\cs_new_protected_nopar:Npn \__regex_store_submatches:
  {
    \tex_toks:D \l__regex_max_active_int \exp_after:wN
      { \l__regex_current_submatches_prop }
  }
\cs_new_protected_nopar:Npn \__regex_disable_submatches:
  {
    \cs_set_protected_nopar:Npn \__regex_store_submatches: { }
    \cs_set_protected:Npn \__regex_action_submatch:n ##1 { }
  }
\cs_new_protected:Npn \__regex_action_submatch:n #1
  {
    \prop_put:Nno \l__regex_current_submatches_prop {#1}
      { \int_use:N \l__regex_current_pos_int }
  }
\cs_new_protected_nopar:Npn \__regex_action_success:
  {
    \__regex_if_two_empty_matches:F
      {
        \bool_set_true:N \l__regex_match_success_bool
        \bool_set_eq:NN \l__regex_empty_success_bool
          \l__regex_fresh_thread_bool
        \int_set_eq:NN \l__regex_success_pos_int \l__regex_current_pos_int
        \prop_set_eq:NN \l__regex_success_submatches_prop
          \l__regex_current_submatches_prop
        \__prg_break:
      }
  }
\int_new:N \l__regex_replacement_csnames_int
\tl_new:N \l__regex_balance_tl
\cs_new:Npn \__regex_replacement_balance_one_match:n #1
  { - \__regex_submatch_balance:n {#1} }
\cs_new:Npn \__regex_replacement_do_one_match:n #1
  {
    \__regex_query_range:nn
      { \etex_glueshrink:D \tex_skip:D #1 }
      { \tex_skip:D #1 }
  }
\cs_new:Npn \__regex_replacement_exp_not:N #1 { \exp_not:n {#1} }
\cs_new:Npn \__regex_query_range:nn #1#2
  {
    \exp_after:wN \__regex_query_range_loop:ww
    \int_use:N \__int_eval:w #1 \exp_after:wN ;
    \int_use:N \__int_eval:w #2 ;
    \__prg_break_point:
  }
\cs_new:Npn \__regex_query_range_loop:ww #1 ; #2 ;
  {
    \if_int_compare:w #1 < #2 \exp_stop_f:
    \else:
      \exp_after:wN \__prg_break:
    \fi:
    \tex_the:D \tex_toks:D #1 \exp_stop_f:
    \exp_after:wN \__regex_query_range_loop:ww
      \int_use:N \__int_eval:w #1 + \c_one ; #2 ;
  }
\cs_new:Npn \__regex_query_submatch:n #1
  {
    \__regex_query_range:nn
      { \tex_skip:D \__int_eval:w #1 }
      { \etex_gluestretch:D \tex_skip:D \__int_eval:w #1 }
  }
\cs_new_protected:Npn \__regex_submatch_balance:n #1
  {
    \etex_glueshrink:D \etex_mutoglue:D \etex_muexpr:D
      \tex_muskip:D \etex_gluestretch:D \tex_skip:D #1
      - \tex_muskip:D \tex_skip:D #1
    \scan_stop:
  }
\cs_new_protected:Npn \__regex_replacement:n #1
  {
    \__tl_build:Nw \l__regex_internal_a_tl
      \int_zero:N \l__regex_balance_int
      \tl_clear:N \l__regex_balance_tl
      \__regex_escape_use:nnnn
        {
          \if_charcode:w \c_right_brace_str ##1
            \__regex_replacement_rbrace:N \else: \__tl_build_one:n \fi: ##1
        }
        { \__regex_replacement_escaped:N ##1 }
        { \__tl_build_one:n ##1 }
        {#1}
      \prg_do_nothing: \prg_do_nothing:
      \if_int_compare:w \l__regex_replacement_csnames_int > \c_zero
        \__msg_kernel_error:nnx { regex } { replacement-missing-rbrace }
          { \int_use:N \l__regex_replacement_csnames_int }
        \__tl_build_one:x
          { \prg_replicate:nn \l__regex_replacement_csnames_int \cs_end: }
      \fi:
      \cs_gset:Npx \__regex_replacement_balance_one_match:n ##1
        {
          + \int_use:N \l__regex_balance_int
          \l__regex_balance_tl
          - \__regex_submatch_balance:n {##1}
        }
    \__tl_build_end:
    \exp_args:No \__regex_replacement_aux:n \l__regex_internal_a_tl
  }
\cs_new_protected:Npn \__regex_replacement_aux:n #1
  {
    \cs_set:Npn \__regex_replacement_do_one_match:n ##1
      {
        \__regex_query_range:nn
          { \etex_glueshrink:D \tex_skip:D ##1 }
          { \tex_skip:D ##1 }
        #1
      }
  }
\cs_new_protected:Npn \__regex_replacement_escaped:N #1
  {
    \cs_if_exist_use:cF { __regex_replacement_#1:w }
      {
        \if_int_compare:w \c_one < 1#1 \exp_stop_f:
          \__regex_replacement_put_submatch:n {#1}
        \else:
          \__tl_build_one:o { \token_to_str:N #1 }
        \fi:
      }
  }
\cs_new_protected:Npn \__regex_replacement_put_submatch:n #1
  {
    \if_int_compare:w #1 < \l__regex_capturing_group_int
      \__tl_build_one:n { \__regex_query_submatch:n { #1 + ##1 } }
      \if_int_compare:w \l__regex_replacement_csnames_int = \c_zero
        \tl_put_right:Nn \l__regex_balance_tl
          { + \__regex_submatch_balance:n { \__int_eval:w #1+##1 \__int_eval_end: } }
      \fi:
    \fi:
  }
\cs_new_protected:Npn \__regex_replacement_g:w #1#2
  {
    \str_if_eq_x:nnTF { #1#2 } { \__tl_build_one:n \c_left_brace_str }
      {
        \int_zero:N \l__regex_internal_a_int
        \__regex_replacement_g_digits:NN
      }
      { \__regex_replacement_error:NNN g #1 #2 }
  }
\cs_new_protected:Npn \__regex_replacement_g_digits:NN #1#2
  {
    \token_if_eq_meaning:NNTF #1 \__tl_build_one:n
      {
        \if_int_compare:w \c_one < 1#2 \exp_stop_f:
          \int_set:Nn \l__regex_internal_a_int
            { \c_ten * \l__regex_internal_a_int + #2 }
          \exp_after:wN \use_i:nnn
          \exp_after:wN \__regex_replacement_g_digits:NN
        \else:
          \exp_after:wN \__regex_replacement_error:NNN
          \exp_after:wN g
        \fi:
      }
      {
        \if_meaning:w \__regex_replacement_rbrace:N #1
          \exp_args:No \__regex_replacement_put_submatch:n
            { \int_use:N \l__regex_internal_a_int }
          \exp_after:wN \use_none:nn
        \else:
          \exp_after:wN \__regex_replacement_error:NNN
          \exp_after:wN g
        \fi:
      }
    #1 #2
  }
\cs_new_protected:Npn \__regex_replacement_c:w #1#2
  {
    \token_if_eq_meaning:NNTF #1 \__tl_build_one:n
      {
        \cs_if_exist_use:cF { __regex_replacement_c_#2:w }
          { \__regex_replacement_error:NNN c #1#2 }
      }
      { \__regex_replacement_error:NNN c #1#2 }
  }
\cs_new_protected_nopar:cpn { __regex_replacement_c_ \c_left_brace_str :w }
  {
    \if_case:w \l__regex_replacement_csnames_int
      \__tl_build_one:n
        { \exp_not:n { \exp_after:wN \__regex_replacement_exp_not:N \cs:w } }
    \else:
      \__tl_build_one:n { \exp_not:n { \exp_after:wN \tl_to_str:N \cs:w } }
    \fi:
    \int_incr:N \l__regex_replacement_csnames_int
  }
\cs_new_protected:Npn \__regex_replacement_u:w #1#2
  {
    \str_if_eq_x:nnTF { #1#2 } { \__tl_build_one:n \c_left_brace_str }
      {
        \if_case:w \l__regex_replacement_csnames_int
          \__tl_build_one:n { \exp_not:n { \exp_after:wN \exp_not:V \cs:w } }
        \else:
          \__tl_build_one:n { \exp_not:n { \exp_after:wN \tl_to_str:V \cs:w } }
        \fi:
        \int_incr:N \l__regex_replacement_csnames_int
      }
      { \__regex_replacement_error:NNN u #1#2 }
  }
\cs_new_protected:Npn \__regex_replacement_rbrace:N #1
  {
    \if_int_compare:w \l__regex_replacement_csnames_int > \c_zero
      \__tl_build_one:n \cs_end:
      \int_decr:N \l__regex_replacement_csnames_int
    \else:
      \__tl_build_one:n #1
    \fi:
  }
\group_begin:
  \cs_new_protected:Npn \__regex_replacement_char:nNN #1#2#3
    {
      \if_meaning:w \prg_do_nothing: #3
        \__msg_kernel_error:nn { regex } { replacement-catcode-end }
      \else:
        \tex_lccode:D \c_zero = `#3 \scan_stop:
        \tl_to_lowercase:n { \__tl_build_one:n {#1} }
      \fi:
    }
  \char_set_catcode_active:N \^^@
  \cs_new_protected_nopar:Npn \__regex_replacement_c_A:w
    { \__regex_replacement_char:nNN { \exp_not:n { \exp_not:N ^^@ } } }
  \char_set_catcode_group_begin:N \^^@
  \cs_new_protected_nopar:Npn \__regex_replacement_c_B:w
    {
      \if_int_compare:w \l__regex_replacement_csnames_int = \c_zero
        \int_incr:N \l__regex_balance_int
      \fi:
      \__regex_replacement_char:nNN
        { \exp_not:n { \exp_after:wN ^^@ \if_false: } \fi: } }
    }
  \cs_new_protected:Npn \__regex_replacement_c_C:w #1#2
    { \__tl_build_one:n { \exp_not:N \exp_not:N \exp_not:c {#2} } }
  \char_set_catcode_math_subscript:N \^^@
  \cs_new_protected_nopar:Npn \__regex_replacement_c_D:w
    { \__regex_replacement_char:nNN { ^^@ } }
  \char_set_catcode_group_end:N \^^@
  \cs_new_protected_nopar:Npn \__regex_replacement_c_E:w
    {
      \if_int_compare:w \l__regex_replacement_csnames_int = \c_zero
        \int_decr:N \l__regex_balance_int
      \fi:
      \__regex_replacement_char:nNN
        { \exp_not:n { \if_false: { \fi:  ^^@ } }
    }
  \char_set_catcode_letter:N \^^@
  \cs_new_protected_nopar:Npn \__regex_replacement_c_L:w
    { \__regex_replacement_char:nNN { ^^@ } }
  \char_set_catcode_math_toggle:N \^^@
  \cs_new_protected_nopar:Npn \__regex_replacement_c_M:w
    { \__regex_replacement_char:nNN { ^^@ } }
  \char_set_catcode_other:N \^^@
  \cs_new_protected_nopar:Npn \__regex_replacement_c_O:w
    { \__regex_replacement_char:nNN { ^^@ } }
  \char_set_catcode_parameter:N \^^@
  \cs_new_protected_nopar:Npn \__regex_replacement_c_P:w
    {
      \__regex_replacement_char:nNN
        { \exp_not:n { \exp_not:n { ^^@^^@^^@^^@ } } }
    }
  \cs_new_protected:Npn \__regex_replacement_c_S:w #1#2
    {
      \if_meaning:w \prg_do_nothing: #2
        \__msg_kernel_error:nn { regex } { replacement-catcode-end }
      \else:
        \if_int_compare:w `#2 = \c_zero
          \__msg_kernel_error:nn { regex } { replacement-null-space }
        \fi:
        \tex_lccode:D 32 = `#2 \scan_stop:
        \tl_to_lowercase:n { \__tl_build_one:n {~} }
      \fi:
    }
  \char_set_catcode_alignment:N \^^@
  \cs_new_protected_nopar:Npn \__regex_replacement_c_T:w
    { \__regex_replacement_char:nNN { ^^@ } }
  \char_set_catcode_math_superscript:N \^^@
  \cs_new_protected_nopar:Npn \__regex_replacement_c_U:w
    { \__regex_replacement_char:nNN { ^^@ } }
\group_end:
\cs_new_protected:Npn \__regex_replacement_error:NNN #1#2#3
  {
    \__msg_kernel_error:nnx { regex } { replacement-#1 } {#3}
    #2 #3
  }
\cs_new_protected:Npn \regex_new:N #1
  { \cs_new_eq:NN #1 \c__regex_no_match_regex }
\cs_new_protected_nopar:Npn \regex_set:Nn #1#2
  {
    \__regex_compile:n {#2}
    \tl_set_eq:NN #1 \l__regex_internal_regex
  }
\cs_new_protected_nopar:Npn \regex_gset:Nn #1#2
  {
    \__regex_compile:n {#2}
    \tl_gset_eq:NN #1 \l__regex_internal_regex
  }
\cs_new_protected_nopar:Npn \regex_const:Nn #1#2
  {
    \__regex_compile:n {#2}
    \tl_const:Nx #1 { \exp_not:o \l__regex_internal_regex }
  }
\cs_new_protected:Npn \regex_show:n #1
  {
    \__regex_compile:n {#1}
    \__regex_show:Nx \l__regex_internal_regex
      { { \tl_to_str:n {#1} } }
  }
\cs_new_protected:Npn \regex_show:N #1
  { \__regex_show:Nx #1 { variable~\token_to_str:N #1 } }
\prg_new_protected_conditional:Npnn \regex_match:nn #1#2 { T , F , TF }
  {
    \__regex_if_match:nn { \__regex_build:n {#1} } {#2}
    \__regex_return:
  }
\prg_new_protected_conditional:Npnn \regex_match:Nn #1#2 { T , F , TF }
  {
    \__regex_if_match:nn { \__regex_build:N #1 } {#2}
    \__regex_return:
  }
\cs_new_protected:Npn \regex_count:nnN #1
  { \__regex_count:nnN { \__regex_build:n {#1} } }
\cs_new_protected:Npn \regex_count:NnN #1
  { \__regex_count:nnN { \__regex_build:N #1 } }
\cs_set_protected:Npn \__regex_tmp:w #1#2#3
  {
    \cs_new_protected:Npn #2 ##1 { #1 { \__regex_build:n {##1} } }
    \cs_new_protected:Npn #3 ##1 { #1 { \__regex_build:N  ##1  } }
    \prg_new_protected_conditional:Npnn #2 ##1##2##3 { T , F , TF }
      { #1 { \__regex_build:n {##1} } {##2} ##3 \__regex_return: }
    \prg_new_protected_conditional:Npnn #3 ##1##2##3 { T , F , TF }
      { #1 { \__regex_build:N  ##1  } {##2} ##3 \__regex_return: }
  }
\__regex_tmp:w \__regex_extract_once:nnN
  \regex_extract_once:nnN \regex_extract_once:NnN
\__regex_tmp:w \__regex_extract_all:nnN
  \regex_extract_all:nnN \regex_extract_all:NnN
\__regex_tmp:w \__regex_replace_once:nnN
  \regex_replace_once:nnN \regex_replace_once:NnN
\__regex_tmp:w \__regex_replace_all:nnN
  \regex_replace_all:nnN \regex_replace_all:NnN
\__regex_tmp:w \__regex_split:nnN \regex_split:nnN \regex_split:NnN
\int_new:N \l__regex_match_count_int
\flag_new:n { __regex_begin }
\flag_new:n { __regex_end }
\int_new:N \l__regex_submatch_int
\int_new:N \l__regex_zeroth_submatch_int
\cs_new_protected_nopar:Npn \__regex_return:
  {
    \if_meaning:w \c_true_bool \g__regex_success_bool
      \prg_return_true:
    \else:
      \prg_return_false:
    \fi:
  }
\cs_new_protected:Npn \__regex_if_match:nn #1#2
  {
    \group_begin:
      \__regex_disable_submatches:
      \__regex_single_match:
      #1
      \__regex_match:n {#2}
    \group_end:
  }
\cs_new_protected:Npn \__regex_count:nnN #1#2#3
  {
    \group_begin:
      \__regex_disable_submatches:
      \int_zero:N \l__regex_match_count_int
      \__regex_multi_match:n { \int_incr:N \l__regex_match_count_int }
      #1
      \__regex_match:n {#2}
      \exp_args:NNNo
    \group_end:
    \int_set:Nn #3 { \int_use:N \l__regex_match_count_int }
  }
\cs_new_protected:Npn \__regex_extract_once:nnN #1#2#3
  {
    \group_begin:
      \__regex_single_match:
      #1
      \__regex_match:n {#2}
      \__regex_extract:
    \__regex_group_end_extract_seq:N #3
  }
\cs_new_protected:Npn \__regex_extract_all:nnN #1#2#3
  {
    \group_begin:
      \__regex_multi_match:n { \__regex_extract: }
      #1
      \__regex_match:n {#2}
    \__regex_group_end_extract_seq:N #3
  }
\cs_new_protected:Npn \__regex_split:nnN #1#2#3
  {
    \group_begin:
      \__regex_multi_match:n
        {
          \if_int_compare:w \l__regex_start_pos_int < \l__regex_success_pos_int
            \__regex_extract:
            \tex_skip:D \l__regex_zeroth_submatch_int
              = \l__regex_start_pos_int sp
                plus \tex_skip:D \l__regex_zeroth_submatch_int \scan_stop:
          \fi:
        }
      #1
      \__regex_match:n {#2}
      \tex_skip:D \l__regex_submatch_int
        = \l__regex_start_pos_int sp plus \l__regex_max_pos_int sp \scan_stop:
      \int_incr:N \l__regex_submatch_int
      \if_meaning:w \c_true_bool \l__regex_empty_success_bool
        \if_int_compare:w \l__regex_start_pos_int = \l__regex_max_pos_int
          \int_decr:N \l__regex_submatch_int
        \fi:
      \fi:
    \__regex_group_end_extract_seq:N #3
  }
\cs_new_protected:Npn \__regex_group_end_extract_seq:N #1
  {
      \cs_set_eq:NN \__seq_item:n \scan_stop:
      \flag_clear:n { __regex_begin }
      \flag_clear:n { __regex_end }
      \tl_set:Nx \l__regex_internal_a_tl
        {
          \s__seq
          \int_step_function:nnnN
            { \c_two * \l__regex_max_state_int }
            \c_one
            { \l__regex_submatch_int - \c_one }
            \__regex_extract_seq_aux:n
        }
      \int_compare:nNnF
        { \flag_height:n { __regex_begin } + \flag_height:n { __regex_end } }
        = \c_zero
        {
          \__msg_kernel_error:nnxxx { regex } { result-unbalanced }
            { splitting~or~extracting~submatches }
            { \flag_height:n { __regex_end } }
            { \flag_height:n { __regex_begin } }
        }
      \use:x
        {
          \group_end:
          \tl_set:Nn \exp_not:N #1 { \l__regex_internal_a_tl }
        }
  }
\cs_new:Npn \__regex_extract_seq_aux:n #1
  {
    \__seq_item:n
      {
        \exp_after:wN \__regex_extract_seq_aux:ww
        \__int_value:w \__regex_submatch_balance:n {#1} ; #1;
      }
  }
\cs_new:Npn \__regex_extract_seq_aux:ww #1; #2;
  {
    \if_int_compare:w #1 < \c_zero
      \flag_raise:n { __regex_end }
      \prg_replicate:nn {-#1} { \exp_not:n { { \if_false: } \fi: } }
    \fi:
    \__regex_query_submatch:n {#2}
    \if_int_compare:w #1 > \c_zero
      \flag_raise:n { __regex_begin }
      \prg_replicate:nn {#1} { \exp_not:n { \if_false: { \fi: } } }
    \fi:
  }
\cs_new_protected_nopar:Npn \__regex_extract:
  {
    \if_meaning:w \c_true_bool \g__regex_success_bool
      \int_set_eq:NN \l__regex_zeroth_submatch_int \l__regex_submatch_int
      \prg_replicate:nn \l__regex_capturing_group_int
        {
          \tex_skip:D \l__regex_submatch_int \c_zero sp \scan_stop:
          \int_incr:N \l__regex_submatch_int
        }
      \prop_map_inline:Nn \l__regex_success_submatches_prop
        {
          \if_int_compare:w ##1 \c_minus_one
            \exp_after:wN \__regex_extract_e:wn \__int_value:w
          \else:
            \exp_after:wN \__regex_extract_b:wn \__int_value:w
          \fi:
          \__int_eval:w \l__regex_zeroth_submatch_int + ##1 {##2}
        }
      \tex_skip:D \l__regex_zeroth_submatch_int
        = \tex_the:D \tex_skip:D \l__regex_zeroth_submatch_int
          minus \l__regex_start_pos_int sp \scan_stop:
    \fi:
  }
\cs_new_protected:Npn \__regex_extract_b:wn #1 < #2
  {
    \tex_skip:D #1 = #2 sp
      plus \etex_gluestretch:D \tex_skip:D #1 \scan_stop:
  }
\cs_new_protected:Npn \__regex_extract_e:wn #1 > #2
  {
    \tex_skip:D #1
      = 1 \tex_skip:D #1 plus #2 sp \scan_stop:
  }
\cs_new_protected:Npn \__regex_replace_once:nnN #1#2#3
  {
    \group_begin:
      \__regex_single_match:
      #1
      \__regex_replacement:n {#2}
      \exp_args:No \__regex_match:n { #3 }
      \if_meaning:w \c_false_bool \g__regex_success_bool
        \group_end:
      \else:
        \__regex_extract:
        \int_set:Nn \l__regex_balance_int
          {
            \__regex_replacement_balance_one_match:n
              { \l__regex_zeroth_submatch_int }
          }
        \tl_set:Nx \l__regex_internal_a_tl
          {
            \__regex_replacement_do_one_match:n { \l__regex_zeroth_submatch_int }
            \__regex_query_range:nn
              { \etex_gluestretch:D \tex_skip:D \l__regex_zeroth_submatch_int }
              { \l__regex_max_pos_int }
          }
        \__regex_group_end_replace:N #3
      \fi:
  }
\cs_new_protected:Npn \__regex_replace_all:nnN #1#2#3
  {
    \group_begin:
      \__regex_multi_match:n { \__regex_extract: }
      #1
      \__regex_replacement:n {#2}
      \exp_args:No \__regex_match:n {#3}
      \int_set:Nn \l__regex_balance_int
        {
          0
          \int_step_function:nnnN
            { \c_two * \l__regex_max_state_int }
            \l__regex_capturing_group_int
            { \l__regex_submatch_int - \c_one }
            \__regex_replacement_balance_one_match:n
        }
      \tl_set:Nx \l__regex_internal_a_tl
        {
          \int_step_function:nnnN
            { \c_two * \l__regex_max_state_int }
            \l__regex_capturing_group_int
            { \l__regex_submatch_int - \c_one }
            \__regex_replacement_do_one_match:n
          \__regex_query_range:nn
            \l__regex_start_pos_int \l__regex_max_pos_int
        }
    \__regex_group_end_replace:N #3
  }
\cs_new_protected_nopar:Npn \__regex_group_end_replace:N #1
  {
    \if_int_compare:w \l__regex_balance_int = \c_zero
    \else:
      \__msg_kernel_error:nnxxx { regex } { result-unbalanced }
        { replacing }
        { \int_max:nn { - \l__regex_balance_int } { \c_zero } }
        { \int_max:nn { \l__regex_balance_int } { \c_zero } }
    \fi:
    \use:x
      {
        \group_end:
        \tl_set:Nn \exp_not:N #1
          {
            \if_int_compare:w \l__regex_balance_int < \c_zero
              \prg_replicate:nn { - \l__regex_balance_int }
                { { \if_false: } \fi: }
            \fi:
            \l__regex_internal_a_tl
            \if_int_compare:w \l__regex_balance_int > \c_zero
              \prg_replicate:nn { \l__regex_balance_int }
                { \if_false: { \fi: } }
            \fi:
          }
      }
  }
\__msg_kernel_new:nnnn { regex } { trailing-backslash }
  { Trailing~escape~character~`\iow_char:N\\'. }
  {
    A~regular~expression~or~its~replacement~text~ends~with~
    the~escape~character~`\iow_char:N\\'.~It~will~be~ignored.
  }
\__msg_kernel_new:nnnn { regex } { x-missing-rbrace }
  { Missing~closing~brace~in~`\iow_char:N\\x'~hexadecimal~sequence. }
  {
    You~wrote~something~like~
    `\iow_char:N\\x\{...#1'.~
    The~closing~brace~is~missing.
  }
\__msg_kernel_new:nnnn { regex } { x-overflow }
  { Character~code~`#1'~too~large~in~`\iow_char:N\\x'~hexadecimal~sequence. }
  {
    You~wrote~something~like~
    `\iow_char:N\\x\{\int_to_hexadecimal:n{#1}\}'.~
    The~character~code~#1~is~larger~than~
    the~maximum~value~\int_use:N \c_max_char_int.
  }
\__msg_kernel_new:nnnn { regex } { invalid-quantifier }
  { Braced~quantifier~`#1'~may~not~be~followed~by~`#2'. }
  {
    The~character~`#2'~is~invalid~in~the~braced~quantifier~`#1'.~
    The~only~valid~quantifiers~are~`*',~`?',~`+',~`{<int>}',~
    `{<min>,}'~and~`{<min>,<max>}',~optionally~followed~by~`?'.
  }
\__msg_kernel_new:nnnn { regex } { missing-rbrack }
  { Missing~right~bracket~inserted~in~regular~expression. }
  {
    LaTeX~was~given~a~regular~expression~where~a~character~class~
    was~started~with~`[',~but~the~matching~`]'~is~missing.
  }
\__msg_kernel_new:nnnn { regex } { missing-rparen }
  {
    Missing~right~
    \int_compare:nTF { #1 = 1 } { parenthesis } { parentheses } ~
    inserted~in~regular~expression.
  }
  {
    LaTeX~was~given~a~regular~expression~with~\int_eval:n {#1} ~
    more~left~parentheses~than~right~parentheses.
  }
\__msg_kernel_new:nnnn { regex } { extra-rparen }
  { Extra~right~parenthesis~ignored~in~regular~expression. }
  {
    LaTeX~came~across~a~closing~parenthesis~when~no~submatch~group~
    was~open.~The~parenthesis~will~be~ignored.
  }
\__msg_kernel_new:nnnn { regex } { bad-escape }
  {
    Invalid~escape~`\iow_char:N\\#1'~
    \__regex_if_in_cs:TF { within~a~control~sequence. }
      {
        \__regex_if_in_class:TF
          { in~a~character~class. }
          { following~a~category~test. }
      }
  }
  {
    The~escape~sequence~`\iow_char:N\\#1'~may~not~appear~
    \__regex_if_in_cs:TF
      {
        within~a~control~sequence~test~introduced~by~
        `\iow_char:N\\c\iow_char:N\{'.
      }
      {
        \__regex_if_in_class:TF
          { within~a~character~class~ }
          { following~a~category~test~such~as~`\iow_char:N\\cL'~ }
        because~it~does~not~match~exactly~one~character.
      }
  }
\__msg_kernel_new:nnnn { regex } { range-missing-end }
  { Invalid~end-point~for~range~`#1-#2'~in~character~class. }
  {
    The~end-point~`#2'~of~the~range~`#1-#2'~may~not~serve~as~an~
    end-point~for~a~range:~alphanumeric~characters~should~not~be~
    escaped,~and~non-alphanumeric~characters~should~be~escaped.
  }
\__msg_kernel_new:nnnn { regex } { range-backwards }
  { Range~`[#1-#2]'~out~of~order~in~character~class. }
  {
    In~ranges~of~characters~`[x-y]'~appearing~in~character~classes,~
    the~first~character~code~must~not~be~larger~than~the~second.~
    Here,~`#1'~has~character~code~\int_eval:n {`#1},~while~
    `#2'~has~character~code~\int_eval:n {`#2}.
  }
\__msg_kernel_new:nnnn { regex } { c-bad-mode }
  { Invalid~nested~`\iow_char:N\\c'~escape~in~regular~expression. }
  {
    The~`\iow_char:N\\c'~escape~cannot~be~used~within~
    a~control~sequence~test~`\iow_char:N\\c{...}'.~
    To~combine~several~category~tests,~use~`\iow_char:N\\c[...]'.
  }
\__msg_kernel_new:nnnn { regex } { c-missing-rbrace }
  { Missing~right~brace~inserted~for~`\iow_char:N\\c'~escape. }
  {
    LaTeX~was~given~a~regular~expression~where~a~
    `\iow_char:N\\c\iow_char:N\{...'~construction~was~not~ended~
    with~a~closing~brace~`\iow_char:N\}'.
  }
\__msg_kernel_new:nnnn { regex } { c-missing-rbrack }
  { Missing~right~bracket~inserted~for~`\iow_char:N\\c'~escape. }
  {
    A~construction~`\iow_char:N\\c[...'~appears~in~a~
    regular~expression,~but~the~closing~`]'~is~not~present.
  }
\__msg_kernel_new:nnnn { regex } { c-missing-category }
  { Invalid~character~`#1'~following~`\iow_char:N\\c'~escape. }
  {
    In~regular~expressions,~the~`\iow_char:N\\c'~escape~sequence~
    may~only~be~followed~by~a~left~brace,~a~left~bracket,~or~a~
    capital~letter~representing~a~character~category,~namely~
    one~of~`ABCDELMOPSTU'.
  }
\__msg_kernel_new:nnnn { regex } { c-trailing }
  { Trailing~category~code~escape~`\iow_char:N\\c'... }
  {
    A~regular~expression~ends~with~`\iow_char:N\\c'~followed~
    by~a~letter.~It~will~be~ignored.
  }
\__msg_kernel_new:nnnn { regex } { u-missing-lbrace }
  { Missing~left~brace~following~`\iow_char:N\\u'~escape. }
  {
    The~`\iow_char:N\\u'~escape~sequence~must~be~followed~by~
    a~brace~group~with~the~name~of~the~variable~to~use.
  }
\__msg_kernel_new:nnnn { regex } { u-missing-rbrace }
  { Missing~right~brace~inserted~for~`\iow_char:N\\u'~escape. }
  {
    LaTeX~
    \str_if_eq_x:nnTF { } {#2}
      { reached~the~end~of~the~string~ }
      { encountered~an~escaped~alphanumeric~character `\iow_char:N\\#2'~ }
    when~parsing~the~argument~of~an~`\iow_char:N\\u\iow_char:N\{...\}'~escape.
  }
\__msg_kernel_new:nnnn { regex } { posix-unsupported }
  { POSIX~collating~element~`[#1 ~ #1]'~not~supported. }
  {
    The~`[.foo.]'~and~`[=bar=]'~syntaxes~have~a~special~meaning~
    in~POSIX~regular~expressions.~This~is~not~supported~by~LaTeX.~
    Maybe~you~forgot~to~escape~a~left~bracket~in~a~character~class?
  }
\__msg_kernel_new:nnnn { regex } { posix-unknown }
  { POSIX~class~`[:#1:]'~unknown. }
  {
    `[:#1:]'~is~not~among~the~known~POSIX~classes~
    `[:alnum:]',~`[:alpha:]',~`[:ascii:]',~`[:blank:]',~
    `[:cntrl:]',~`[:digit:]',~`[:graph:]',~`[:lower:]',~
    `[:print:]',~`[:punct:]',~`[:space:]',~`[:upper:]',~
    `[:word:]',~and~`[:xdigit:]'.
  }
\__msg_kernel_new:nnnn { regex } { posix-missing-close }
  { Missing~closing~`:]'~for~POSIX~class. }
  { The~POSIX~syntax~`#1'~must~be~followed~by~`:]',~not~`#2'. }
\__msg_kernel_new:nnnn { regex } { result-unbalanced }
  { Missing~brace~inserted~when~#1. }
  {
    LaTeX~was~asked~to~do~some~regular~expression~operation,~
    and~the~resulting~token~list~would~not~have~the~same~number~
    of~begin-group~and~end-group~tokens.~Braces~were~inserted:~
    #2~left,~#3~right.
  }
\__msg_kernel_new:nnnn { regex } { unknown-option }
  { Unknown~option~`#1'~for~regular~expressions. }
  {
    The~only~available~option~is~`case-insensitive',~toggled~by~
    `(?i)'~and~`(?-i)'.
  }
\__msg_kernel_new:nnnn { regex } { special-group-unknown }
  { Unknown~special~group~`#1~...'~in~a~regular~expression. }
  {
    The~only~valid~constructions~starting~with~`(?'~are~
    `(?:~...~)',~`(?|~...~)',~`(?i)',~and~`(?-i)'.
  }
\__msg_kernel_new:nnnn { regex } { replacement-c }
  { Misused~`\iow_char:N\\c'~command~in~a~replacement~text. }
  {
    In~a~replacement~text,~the~`\iow_char:N\\c'~escape~sequence~
    can~be~followed~by~one~of~the~letters~`ABCDELMOPSTU'~
    or~a~brace~group,~not~by~`#1'.
  }
\__msg_kernel_new:nnnn { regex } { replacement-u }
  { Misused~`\iow_char:N\\u'~command~in~a~replacement~text. }
  {
    In~a~replacement~text,~the~`\iow_char:N\\u'~escape~sequence~
    must~be~~followed~by~a~brace~group~holding~the~name~of~the~
    variable~to~use.
  }
\__msg_kernel_new:nnnn { regex } { replacement-g }
  {
    Missing~brace~for~the~`\iow_char:N\\g'~construction~
    in~a~replacement~text.
  }
  {
    In~the~replacement~text~for~a~regular~expression~search,~
    submatches~are~represented~either~as~`\iow_char:N \\g{dd..d}',~
    or~`\\d',~where~`d'~are~single~digits.~Here,~a~brace~is~missing.
  }
\__msg_kernel_new:nnnn { regex } { replacement-catcode-end }
  {
    Missing~character~for~the~`\iow_char:N\\c<category><character>'~
    construction~in~a~replacement~text.
  }
  {
    In~a~replacement~text,~the~`\iow_char:N\\c'~escape~sequence~
    can~be~followed~by~one~of~the~letters~`ABCDELMOPSTU'~representing~
    the~character~category.~Then,~a~character~must~follow.~LaTeX~
    reached~the~end~of~the~replacement~when~looking~for~that.
  }
\__msg_kernel_new:nnnn { regex } { replacement-null-space }
  { TeX~cannot~build~a~space~token~with~character~code~0. }
  {
    You~asked~for~a~character~token~with~category~space,~
    and~character~code~0,~for~instance~through~
    `\iow_char:N\\cS\iow_char:N\\x00'.~
    This~specific~case~is~impossible~and~will~be~replaced~
    by~a~normal~space.
  }
\__msg_kernel_new:nnnn { regex } { replacement-missing-rbrace }
  { Missing~right~brace~inserted~in~replacement~text. }
  {
    There~ \int_compare:nTF { #1 = 1 } { was } { were } ~ #1~
    missing~right~\int_compare:nTF { #1 = 1 } { brace } { braces } .
  }
\cs_new:Npn \__regex_msg_repeated:nnN #1#2#3
  {
    \str_if_eq_x:nnF { #1 #2 } { 1 0 }
      {
        , ~ repeated ~
        \int_case:nnF {#2}
          {
            { -1 } { #1~or~more~times,~\bool_if:NTF #3 { lazy } { greedy } }
            {  0 } { #1~times }
          }
          {
            between~#1~and~\int_eval:n {#1+#2}~times,~
            \bool_if:NTF #3 { lazy } { greedy }
          }
      }
  }
%% 
%%
%% End of file `l3regex.sty'.
