@@ -1707,9 +1707,9 @@ def private re_match2_repeat_lazy(var regex : Regex; var node : ReNode?; str : u
17071707
17081708def private re_early_out (var cset : CharSet; node : ReNode?) : bool {
17091709 if (node .op == ReOp .Char ) {
1710- set_or_char (cset , character_at (node .text , 0 ))
1710+ let fc = first_character (node .text )
1711+ set_or_char (cset , fc )
17111712 // if case-insensitive, also add the opposite-case first char
1712- let fc = character_at (node .text , 0 )
17131713 if (fc > = 'A' && fc < = 'Z' ) {
17141714 set_or_char (cset , fc + 32 )
17151715 } elif (fc > = 'a' && fc < = 'z' ) {
@@ -1953,53 +1953,58 @@ def private expand_replacement(var regex : Regex; str : string; replacement : st
19531953 //! Expands replacement template with group references: $0 or $& for whole match,
19541954 //! $1-$9 for numbered groups, ${name} for named groups, $$ for literal $.
19551955 return build_string () $ (writer) {
1956- var i = 0
19571956 let rlen = length (replacement )
1958- while (i < rlen ) {
1959- let ch = character_at (replacement , i )
1960- if (ch == '$' && i + 1 < rlen ) {
1961- let nch = character_at (replacement , i + 1 )
1962- if (nch == '$' ) {
1963- writer | > write_char ('$' )
1964- i + = 2
1965- } elif (nch == '&' || nch == '0' ) {
1966- writer | > write (slice (str , match_start , match_end ))
1967- i + = 2
1968- } elif (nch > = '1' && nch < = '9' ) {
1969- let group_num = nch - '0'
1970- if (group_num < length (regex .groups )) {
1971- let grng = regex .groups [group_num ]._0
1972- writer | > write (slice (str , grng .x , grng .y ))
1973- }
1974- i + = 2
1975- } elif (nch == '{' ) {
1976- let close = find (replacement , "}" , i + 2 )
1977- if (close ! = - 1 ) {
1978- let name = slice (replacement , i + 2 , close )
1979- // try numeric group reference first (${0}, ${1}, ...)
1980- var is_numeric = ! empty (name )
1981- for (nc in name ) {
1982- if (nc < '0' || nc > '9' ) {
1983- is_numeric = false
1984- break
1985- }
1957+ peek_data (replacement ) $ (rdata) {
1958+ var i = 0
1959+ while (i < rlen ) {
1960+ let ch = int (rdata [i ])
1961+ if (ch == '$' && i + 1 < rlen ) {
1962+ let nch = int (rdata [i + 1 ])
1963+ if (nch == '$' ) {
1964+ writer | > write_char ('$' )
1965+ i + = 2
1966+ } elif (nch == '&' || nch == '0' ) {
1967+ writer | > write (slice (str , match_start , match_end ))
1968+ i + = 2
1969+ } elif (nch > = '1' && nch < = '9' ) {
1970+ let group_num = nch - '0'
1971+ if (group_num < length (regex .groups )) {
1972+ let grng = regex .groups [group_num ]._0
1973+ writer | > write (slice (str , grng .x , grng .y ))
19861974 }
1987- if (is_numeric ) {
1988- var group_num = 0
1975+ i + = 2
1976+ } elif (nch == '{' ) {
1977+ let close = find (replacement , "}" , i + 2 )
1978+ if (close ! = - 1 ) {
1979+ let name = slice (replacement , i + 2 , close )
1980+ // try numeric group reference first (${0}, ${1}, ...)
1981+ var is_numeric = ! empty (name )
19891982 for (nc in name ) {
1990- group_num = group_num * 10 + (nc - '0' )
1983+ if (nc < '0' || nc > '9' ) {
1984+ is_numeric = false
1985+ break
1986+ }
19911987 }
1992- if (group_num == 0 ) {
1993- writer | > write (slice (str , match_start , match_end ))
1994- } elif (group_num < length (regex .groups )) {
1995- let grng = regex .groups [group_num ]._0
1996- writer | > write (slice (str , grng .x , grng .y ))
1988+ if (is_numeric ) {
1989+ var group_num = 0
1990+ for (nc in name ) {
1991+ group_num = group_num * 10 + (nc - '0' )
1992+ }
1993+ if (group_num == 0 ) {
1994+ writer | > write (slice (str , match_start , match_end ))
1995+ } elif (group_num < length (regex .groups )) {
1996+ let grng = regex .groups [group_num ]._0
1997+ writer | > write (slice (str , grng .x , grng .y ))
1998+ }
1999+ } else {
2000+ let grp = regex_group_by_name (regex , name , str )
2001+ writer | > write (grp )
19972002 }
2003+ i = close + 1
19982004 } else {
1999- let grp = regex_group_by_name ( regex , name , str )
2000- writer | > write ( grp )
2005+ writer | > write_char ( ch )
2006+ i ++
20012007 }
2002- i = close + 1
20032008 } else {
20042009 writer | > write_char (ch )
20052010 i ++
@@ -2008,9 +2013,6 @@ def private expand_replacement(var regex : Regex; str : string; replacement : st
20082013 writer | > write_char (ch )
20092014 i ++
20102015 }
2011- } else {
2012- writer | > write_char (ch )
2013- i ++
20142016 }
20152017 }
20162018 }
0 commit comments