%% %% This is file `l3regex.sty', %% generated with the docstrip utility. %% %% The original source files were: %% %% l3regex.dtx (with options: `package') %% %% Copyright (C) 2011-2016 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. %% %% File: l3regex.dtx Copyright (C) 2011-2017 The LaTeX3 Project \RequirePackage{expl3}[2017/03/07] \@ifpackagelater{expl3}{2017/03/07} {} {% \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 6984 2017-03-07 20:53:23Z joseph $ {L3 Experimental regular expressions} \ProvidesExplPackage {\ExplFileName}{\ExplFileDate}{\ExplFileVersion}{\ExplFileDescription} \RequirePackage{l3tl-build, l3tl-analysis, 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: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 > `Z \exp_stop_f: \if_int_compare:w \l__regex_current_char_int > `z \exp_stop_f: \else: \if_int_compare:w \l__regex_current_char_int < `a \exp_stop_f: \else: \int_sub:Nn \l__regex_case_changed_char_int { \c__str_ascii_lower_int } \fi: \fi: \else: \if_int_compare:w \l__regex_current_char_int < `A \exp_stop_f: \else: \int_add:Nn \l__regex_case_changed_char_int { \c__str_ascii_lower_int } \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*0 \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:n #1 { \int_compare:nNnTF \l__regex_current_catcode_int = 0 { \tl_set:Nx \l__regex_internal_a_tl { \scan_stop: \exp_after:wN \exp_after:wN \exp_after:wN \cs_to_str:N \tex_the:D \tex_toks:D \l__regex_current_pos_int \scan_stop: } \tl_if_in:noTF { \scan_stop: #1 \scan_stop: } \l__regex_internal_a_tl { \__regex_break_true:w } { } } { } } \cs_new_protected:Npn \__regex_item_cs:n #1 { \int_compare:nNnT \l__regex_current_catcode_int = 0 { \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:Npn \__regex_prop_d: { \__regex_item_caseful_range:nn { `0 } { `9 } } \cs_new_protected:Npn \__regex_prop_h: { \__regex_item_caseful_equal:n { `\ } \__regex_item_caseful_equal:n { `\^^I } } \cs_new_protected:Npn \__regex_prop_s: { \__regex_item_caseful_equal:n { `\ } \__regex_item_caseful_equal:n { `\^^I } \__regex_item_caseful_equal:n { `\^^J } \__regex_item_caseful_equal:n { `\^^L } \__regex_item_caseful_equal:n { `\^^M } } \cs_new_protected:Npn \__regex_prop_v: { \__regex_item_caseful_range:nn { `\^^J } { `\^^M } } % lf, vtab, ff, cr \cs_new_protected:Npn \__regex_prop_w: { \__regex_item_caseful_range:nn { `a } { `z } \__regex_item_caseful_range:nn { `A } { `Z } \__regex_item_caseful_range:nn { `0 } { `9 } \__regex_item_caseful_equal:n { `_ } } \cs_new_protected:Npn \__regex_prop_N: { \__regex_item_reverse:n { \__regex_item_caseful_equal:n { `\^^J } } } \cs_new_protected:Npn \__regex_posix_alnum: { \__regex_posix_alpha: \__regex_posix_digit: } \cs_new_protected:Npn \__regex_posix_alpha: { \__regex_posix_lower: \__regex_posix_upper: } \cs_new_protected:Npn \__regex_posix_ascii: { \__regex_item_caseful_range:nn \c__str_ascii_min_int \c__str_ascii_max_int } \cs_new_eq:NN \__regex_posix_blank: \__regex_prop_h: \cs_new_protected:Npn \__regex_posix_cntrl: { \__regex_item_caseful_range:nn \c__str_ascii_min_int \c__str_ascii_max_control_int \__regex_item_caseful_equal:n \c__str_ascii_max_int } \cs_new_eq:NN \__regex_posix_digit: \__regex_prop_d: \cs_new_protected:Npn \__regex_posix_graph: { \__regex_item_caseful_range:nn { `! } { `\~ } } \cs_new_protected:Npn \__regex_posix_lower: { \__regex_item_caseful_range:nn { `a } { `z } } \cs_new_protected:Npn \__regex_posix_print: { \__regex_item_caseful_range:nn { `\ } { `\~ } } \cs_new_protected:Npn \__regex_posix_punct: { \__regex_item_caseful_range:nn { `! } { `/ } \__regex_item_caseful_range:nn { `: } { `@ } \__regex_item_caseful_range:nn { `[ } { `` } \__regex_item_caseful_range:nn { `\{ } { `\~ } } \cs_new_protected:Npn \__regex_posix_space: { \__regex_item_caseful_equal:n { `\ } \__regex_item_caseful_range:nn { `\^^I } { `\^^M } } \cs_new_protected:Npn \__regex_posix_upper: { \__regex_item_caseful_range:nn { `A } { `Z } } \cs_new_eq:NN \__regex_posix_word: \__regex_prop_w: \cs_new_protected:Npn \__regex_posix_xdigit: { \__regex_posix_digit: \__regex_item_caseful_range:nn { `A } { `F } \__regex_item_caseful_range:nn { `a } { `f } } \cs_new_protected:Npn \__regex_escape_use:nnnn #1#2#3#4 { \__tl_build:Nw \l__regex_internal_a_tl \cs_set:Npn \__regex_escape_unescaped:N ##1 { #1 } \cs_set:Npn \__regex_escape_escaped:N ##1 { #2 } \cs_set:Npn \__regex_escape_raw:N ##1 { #3 } \int_set:Nn \tex_escapechar:D { `\\ } \__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: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: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:cpn { __regex_escape_~:w } { } \cs_new:cpx { __regex_escape_/a:w } { \exp_not:N \__regex_escape_raw:N \iow_char:N \^^G } \cs_new:cpx { __regex_escape_/t:w } { \exp_not:N \__regex_escape_raw:N \iow_char:N \^^I } \cs_new:cpx { __regex_escape_/n:w } { \exp_not:N \__regex_escape_raw:N \iow_char:N \^^J } \cs_new:cpx { __regex_escape_/f:w } { \exp_not:N \__regex_escape_raw:N \iow_char:N \^^L } \cs_new:cpx { __regex_escape_/r:w } { \exp_not:N \__regex_escape_raw:N \iow_char:N \^^M } \cs_new: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__str_max_byte_int { \__regex_escape_x_large:n {#1} } { \exp_last_unbraced:Nf \__regex_escape_raw:N { \__str_output_byte: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 { 0 } {#1} \tex_lowercase:D { \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 > `Z \exp_stop_f: \if_int_compare:w `#1 > `z \exp_stop_f: \if_int_compare:w `#1 < \c__str_ascii_max_int \prg_return_true: \else: \prg_return_false: \fi: \else: \if_int_compare:w `#1 < `a \exp_stop_f: \prg_return_true: \else: \prg_return_false: \fi: \fi: \else: \if_int_compare:w `#1 > `9 \exp_stop_f: \if_int_compare:w `#1 < `A \exp_stop_f: \prg_return_true: \else: \prg_return_false: \fi: \else: \if_int_compare:w `#1 < `0 \exp_stop_f: \if_int_compare:w `#1 < `\ \exp_stop_f: \prg_return_false: \else: \prg_return_true: \fi: \else: \prg_return_false: \fi: \fi: \fi: } \prg_new_conditional:Npnn \__regex_char_if_alphanumeric:N #1 { TF } { \if_int_compare:w `#1 > `Z \exp_stop_f: \if_int_compare:w `#1 > `z \exp_stop_f: \prg_return_false: \else: \if_int_compare:w `#1 < `a \exp_stop_f: \prg_return_false: \else: \prg_return_true: \fi: \fi: \else: \if_int_compare:w `#1 > `9 \exp_stop_f: \if_int_compare:w `#1 < `A \exp_stop_f: \prg_return_false: \else: \prg_return_true: \fi: \else: \if_int_compare:w `#1 < `0 \exp_stop_f: \prg_return_false: \else: \prg_return_true: \fi: \fi: \fi: } \int_new:N \l__regex_group_level_int \int_new:N \l__regex_mode_int \int_const:Nn \c__regex_cs_in_class_mode_int { -6 } \int_const:Nn \c__regex_cs_mode_int { -2 } \int_const:Nn \c__regex_outer_mode_int { 0 } \int_const:Nn \c__regex_catcode_mode_int { 2 } \int_const:Nn \c__regex_class_mode_int { 3 } \int_const:Nn \c__regex_catcode_in_class_mode_int { 6 } \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 1 < 1 #2 \exp_stop_f: \prg_return_true: \else: \prg_return_false: \fi: \else: \prg_return_false: \fi: } \cs_new: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: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__regex_outer_mode_int \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: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__regex_outer_mode_int \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:Npn \__regex_if_within_catcode:TF { \if_int_compare:w \l__regex_mode_int > \c__regex_outer_mode_int \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__regex_outer_mode_int \exp_after:wN \use:n \else: \if_int_compare:w \l__regex_mode_int = \c__regex_class_mode_int \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__regex_catcode_mode_int \int_set_eq:NN \l__regex_mode_int \c__regex_outer_mode_int \else: \if_int_compare:w \l__regex_mode_int = \c__regex_catcode_in_class_mode_int \int_set_eq:NN \l__regex_mode_int \c__regex_class_mode_int \fi: \fi: } \cs_new_protected: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:Npn \__regex_item_equal:n { \__regex_item_caseful_equal:n } \cs_set:Npn \__regex_item_range:nn { \__regex_item_caseful_range:nn } \__tl_build_one:n { \__regex_branch:n { \if_false: } \fi: } } \cs_new_protected: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 > 0 \exp_stop_f: \__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 { `\\ } \int_set_eq:NN \l__regex_mode_int \c__regex_outer_mode_int \__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__regex_catcode_mode_int { \__msg_kernel_error:nn { regex } { c-trailing } } \int_compare:nNnT \l__regex_mode_int < \c__regex_outer_mode_int { \__msg_kernel_error:nn { regex } { c-missing-rbrace } \__regex_compile_end_cs: \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:cpn { __regex_compile_quantifier_?:w } { \__regex_compile_quantifier_lazyness:nnNN { 0 } { 1 } } \cs_new_protected:cpn { __regex_compile_quantifier_*:w } { \__regex_compile_quantifier_lazyness:nnNN { 0 } { -1 } } \cs_new_protected: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:nnF { #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: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:cpn { __regex_prop_.: } { \if_int_compare:w \l__regex_current_char_int > - 2 \exp_stop_f: \exp_after:wN \__regex_break_true:w \fi: } \cs_set_protected:Npn \__regex_tmp:w #1#2 { \cs_new_protected:cpx { __regex_compile_/#1: } { \__regex_compile_one:x \exp_not:c { __regex_prop_#1: } } \cs_new_protected: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: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: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: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: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: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__regex_catcode_in_class_mode_int \__tl_build_one:n { \if_false: { \fi: } } \fi: \tex_advance:D \l__regex_mode_int - 15 \exp_stop_f: \tex_divide:D \l__regex_mode_int 13 \exp_stop_f: \if_int_odd:w \l__regex_mode_int \else: \exp_after:wN \__regex_compile_quantifier:w \fi: } { \__regex_compile_raw:N ] } } \cs_new_protected: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: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__regex_catcode_mode_int \__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 > 0 \exp_stop_f: \__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: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: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:cpn { __regex_compile_): } { \__regex_if_in_class:TF { \__regex_compile_raw:N ) } { \__regex_compile_group_end: } } \cs_new_protected:cpn { __regex_compile_special_group_::w } { \__regex_compile_group_begin:N \__regex_group_no_capture:nnnN } \cs_new_protected: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:Npn \__regex_item_equal:n { \__regex_item_caseless_equal:n } \cs_set: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: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:Npn \__regex_item_equal:n { \__regex_item_caseful_equal:n } \cs_set: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__regex_catcode_mode_int \else: \c__regex_catcode_in_class_mode_int \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__regex_catcode_mode_int \else: \c__regex_catcode_in_class_mode_int \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: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: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__regex_cs_mode_int \else: \c__regex_cs_in_class_mode_int \fi: } \flag_new:n { __regex_cs } \cs_new_protected:cpn { __regex_compile_ \c_right_brace_str : } { \__regex_if_in_cs:TF { \__regex_compile_end_cs: } { \exp_after:wN \__regex_compile_raw:N \c_right_brace_str } } \cs_new_protected:Npn \__regex_compile_end_cs: { \__regex_compile_end: \flag_clear:n { __regex_cs } \tl_set:Nx \l__regex_internal_a_tl { \exp_after:wN \__regex_compile_cs_aux:Nn \l__regex_internal_regex \q_nil \q_nil \q_recursion_stop } \exp_args:Nx \__regex_compile_one:x { \flag_if_raised:nTF { __regex_cs } { \__regex_item_cs:n { \exp_not:o \l__regex_internal_regex } } { \__regex_item_exact_cs:n { \tl_tail:N \l__regex_internal_a_tl } } } } \cs_new:Npn \__regex_compile_cs_aux:Nn #1#2 { \cs_if_eq:NNTF #1 \__regex_branch:n { \scan_stop: \__regex_compile_cs_aux:NNnnnN #2 \q_nil \q_nil \q_nil \q_nil \q_nil \q_nil \q_recursion_stop \__regex_compile_cs_aux:Nn } { \quark_if_nil:NF #1 { \flag_raise:n { __regex_cs } } \use_none_delimit_by_q_recursion_stop:w } } \cs_new:Npn \__regex_compile_cs_aux:NNnnnN #1#2#3#4#5#6 { \bool_lazy_all:nTF { { \cs_if_eq_p:NN #1 \__regex_class:NnnnN } {#2} { \tl_if_head_eq_meaning_p:nN {#3} \__regex_item_caseful_equal:n } { \int_compare_p:nNn { \tl_count:n {#3} } = { 2 } } { \int_compare_p:nNn {#5} = { 0 } } } { \prg_replicate:nn {#4} { \char_generate:nn { \use_ii:nn #3 } {12} } \__regex_compile_cs_aux:NNnnnN } { \quark_if_nil:NF #1 { \flag_raise:n { __regex_cs } \use_i_delimit_by_q_recursion_stop:nw } \use_none_delimit_by_q_recursion_stop:w } } \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__regex_outer_mode_int \__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 = 0 \exp_stop_f: \__regex_item_exact_cs:n { \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:cpn { __regex_compile_/K: } { \int_compare:nNnTF \l__regex_mode_int = \c__regex_outer_mode_int { \__tl_build_one:n { \__regex_command_K: } } { \__regex_compile_raw_error:N K } } \cs_new_protected:Npn \__regex_show:Nn #1#2 { \__tl_build:Nw \l__regex_internal_a_tl \cs_set_protected: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:Npn \__regex_group:nnnN { \__regex_show_group_aux:nnnnN { } } \cs_set_protected:Npn \__regex_group_no_capture:nnnN { \__regex_show_group_aux:nnnnN { ~(no~capture) } } \cs_set_protected: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: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: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_eq:NN \__regex_item_exact_cs:n \__regex_show_item_exact_cs:n \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 { ~ } \cs_if_exist_use:N #1 \__tl_build_end: \__msg_show_variable:NNNnn #1 \cs_if_exist:NTF ? { } { >~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) } } { } } \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 } } \cs_new_protected:Npn \__regex_show_item_exact_cs:n #1 { \seq_set_split:Nnn \l__regex_internal_seq { \scan_stop: } {#1} \seq_set_map:NNn \l__regex_internal_seq \l__regex_internal_seq { \iow_char:N\\##1 } \__regex_show_one:n { control~sequence~ \seq_use:Nn \l__regex_internal_seq { ~or~ } } } \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 { `\\ } \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: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: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: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: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: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: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 = 0 \exp_stop_f: \__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 - 1 } \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 = 0 \exp_stop_f: \__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: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 = 0 \exp_stop_f: \int_set:Nn \l__regex_max_state_int { \l__regex_left_state_int - 1 } \__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 > - 1 \exp_stop_f: \__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 > 1 \exp_stop_f: \int_set:Nn \l__regex_internal_c_int { ( #1 - 1 ) * ( \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 \int_incr:N \l__regex_internal_a_int \int_incr:N \l__regex_internal_b_int } \fi: } \cs_new_protected:Npn \__regex_group_repeat:nnN #1#2#3 { \if_int_compare:w #2 = 0 \exp_stop_f: \__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 - 1 } \__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 - 1 } { \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 = 0 \exp_stop_f: \int_set:Nn \l__regex_right_state_int { \l__regex_left_state_int - 1 } \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: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: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 { 2 * \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 { 1 } { \l__regex_max_state_int - 1 } { \tex_dimen:D ##1 ~ 1 sp \scan_stop: } \int_set_eq:NN \l__regex_min_active_int \l__regex_max_state_int \int_zero:N \l__regex_step_int \int_set_eq:NN \l__regex_success_pos_int \l__regex_min_pos_int \int_set:Nn \l__regex_submatch_int { 2 * \l__regex_max_state_int } \bool_set_false:N \l__regex_empty_success_bool \__regex_match_once: } \cs_new_protected:Npn \__regex_match_once: { \if_meaning:w \c_true_bool \l__regex_empty_success_bool \cs_set: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 - 1 } \__regex_query_get: \__regex_match_loop: \l__regex_every_match_tl } \cs_new_protected: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:Npn \__regex_match_loop: { \tex_advance:D \l__regex_step_int 2 \exp_stop_f: \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_value:w \__int_eval:w #1 + 1 \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: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: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 + 1 \__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: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:Npn \__regex_action_free:n { \__regex_action_free_aux:nn { > \l__regex_step_int \else: } } \cs_new_protected: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_value:w \__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:Npn \__regex_store_submatches: { \tex_toks:D \l__regex_max_active_int \exp_after:wN { \l__regex_current_submatches_prop } } \cs_new_protected:Npn \__regex_disable_submatches: { \cs_set_protected: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: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_value:w \__int_eval:w #1 \exp_after:wN ; \__int_value:w \__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_value:w \__int_eval:w #1 + 1 ; #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 > 0 \exp_stop_f: \__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 1 < 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 = 0 \exp_stop_f: \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 1 < 1#2 \exp_stop_f: \int_set:Nn \l__regex_internal_a_int { 10 * \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: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 > 0 \exp_stop_f: \__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 0 = `#3 \scan_stop: \tex_lowercase:D { \__tl_build_one:n {#1} } \fi: } \char_set_catcode_active:N \^^@ \cs_new_protected: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:Npn \__regex_replacement_c_B:w { \if_int_compare:w \l__regex_replacement_csnames_int = 0 \exp_stop_f: \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:Npn \__regex_replacement_c_D:w { \__regex_replacement_char:nNN { ^^@ } } \char_set_catcode_group_end:N \^^@ \cs_new_protected:Npn \__regex_replacement_c_E:w { \if_int_compare:w \l__regex_replacement_csnames_int = 0 \exp_stop_f: \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:Npn \__regex_replacement_c_L:w { \__regex_replacement_char:nNN { ^^@ } } \char_set_catcode_math_toggle:N \^^@ \cs_new_protected:Npn \__regex_replacement_c_M:w { \__regex_replacement_char:nNN { ^^@ } } \char_set_catcode_other:N \^^@ \cs_new_protected:Npn \__regex_replacement_c_O:w { \__regex_replacement_char:nNN { ^^@ } } \char_set_catcode_parameter:N \^^@ \cs_new_protected: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 = 0 \exp_stop_f: \__msg_kernel_error:nn { regex } { replacement-null-space } \fi: \tex_lccode:D `\ = `#2 \scan_stop: \tex_lowercase:D { \__tl_build_one:n {~} } \fi: } \char_set_catcode_alignment:N \^^@ \cs_new_protected:Npn \__regex_replacement_c_T:w { \__regex_replacement_char:nNN { ^^@ } } \char_set_catcode_math_superscript:N \^^@ \cs_new_protected: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:Npn \regex_set:Nn #1#2 { \__regex_compile:n {#2} \tl_set_eq:NN #1 \l__regex_internal_regex } \cs_new_protected:Npn \regex_gset:Nn #1#2 { \__regex_compile:n {#2} \tl_gset_eq:NN #1 \l__regex_internal_regex } \cs_new_protected: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:Nn \l__regex_internal_regex { { \tl_to_str:n {#1} } } } \cs_new_protected:Npn \regex_show:N #1 { \__regex_show:Nn #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: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 { 2 * \l__regex_max_state_int } { 1 } { \l__regex_submatch_int - 1 } \__regex_extract_seq_aux:n } \int_compare:nNnF { \flag_height:n { __regex_begin } + \flag_height:n { __regex_end } } = 0 { \__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 < 0 \exp_stop_f: \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 > 0 \exp_stop_f: \flag_raise:n { __regex_begin } \prg_replicate:nn {#1} { \exp_not:n { \if_false: { \fi: } } } \fi: } \cs_new_protected: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 0 sp \scan_stop: \int_incr:N \l__regex_submatch_int } \prop_map_inline:Nn \l__regex_success_submatches_prop { \if_int_compare:w ##1 - 1 \exp_stop_f: \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 { 2 * \l__regex_max_state_int } \l__regex_capturing_group_int { \l__regex_submatch_int - 1 } \__regex_replacement_balance_one_match:n } \tl_set:Nx \l__regex_internal_a_tl { \int_step_function:nnnN { 2 * \l__regex_max_state_int } \l__regex_capturing_group_int { \l__regex_submatch_int - 1 } \__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:Npn \__regex_group_end_replace:N #1 { \if_int_compare:w \l__regex_balance_int = 0 \exp_stop_f: \else: \__msg_kernel_error:nnxxx { regex } { result-unbalanced } { replacing } { \int_max:nn { - \l__regex_balance_int } { 0 } } { \int_max:nn { \l__regex_balance_int } { 0 } } \fi: \use:x { \group_end: \tl_set:Nn \exp_not:N #1 { \if_int_compare:w \l__regex_balance_int < 0 \exp_stop_f: \prg_replicate:nn { - \l__regex_balance_int } { { \if_false: } \fi: } \fi: \l__regex_internal_a_tl \if_int_compare:w \l__regex_balance_int > 0 \exp_stop_f: \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_Hex: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~`*',~`?',~`+',~`{}',~ `{,}'~and~`{,}',~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'~ 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'.