1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
| | %prep
if ! zmodload -F zsh/re2 C:re2-match 2>/dev/null
then
ZTST_unimplemented="the zsh/re2 module is not available"
return 0
fi
# Load the rest of the builtins
zmodload zsh/re2
# TODO: use future mechanism to switch =~ to use re2 and test =~ too
# Find a UTF-8 locale.
setopt multibyte
# Don't let LC_* override our choice of locale.
unset -m LC_\*
mb_ok=
langs=(en_{US,GB}.{UTF-,utf}8 en.UTF-8
$(locale -a 2>/dev/null | egrep 'utf8|UTF-8'))
for LANG in $langs; do
if [[ é = ? ]]; then
mb_ok=1
break;
fi
done
if [[ -z $mb_ok ]]; then
ZTST_unimplemented="no UTF-8 locale or multibyte mode is not implemented"
else
print -u $ZTST_fd Testing RE2 multibyte with locale $LANG
mkdir multibyte.tmp && cd multibyte.tmp
fi
%test
[[ 'foo→bar' -re2-match .([^[:ascii:]]). ]]
print $MATCH
print $match[1]
0:Basic non-ASCII regexp matching
>o→b
>→
[[ alphabeta -re2-match a([^a]+)a ]]
echo "$? basic"
print $MATCH
print $match[1]
[[ ! alphabeta -re2-match a(.+)a ]]
echo "$? negated op"
[[ alphabeta -re2-match ^b ]]
echo "$? failed match"
# default matches on first, then takes longest substring
# -longest keeps looking
[[ abb -re2-match a(b|bb) ]]
echo "$? first .${MATCH}.${match[1]}."
[[ abb -re2-match-longest a(b|bb) ]]
echo "$? longest .${MATCH}.${match[1]}."
[[ alphabeta -re2-match ab ]]; echo "$? unanchored"
[[ alphabeta -re2-match ^ab ]]; echo "$? anchored"
[[ alphabeta -re2-match '^a(\w+)a$' ]]
echo "$? perl class used"
echo ".${MATCH}. .${match[1]}."
[[ alphabeta -re2-match-posix '^a(\w+)a$' ]]
echo "$? POSIX-mode, should inhibit Perl class"
[[ alphabeta -re2-match-posixperl '^a(\w+)a$' ]]
echo "$? POSIX-mode with Perl classes enabled .${match[1]}."
unset MATCH match
[[ alphabeta -re2-match ^a([^a]+)a([^a]+)a$ ]]
echo "$? matched, set vars"
echo ".$MATCH. ${#MATCH}"
echo ".${(j:|:)match[*]}."
unset MATCH match
[[ alphabeta -re2-match fr(.+)d ]]
echo "$? unmatched, not setting MATCH/match"
echo ".$MATCH. ${#MATCH}"
echo ".${(j:|:)match[*]}."
0:Basic matching & result codes
>0 basic
>alpha
>lph
>1 negated op
>1 failed match
>0 first .ab.b.
>0 longest .abb.bb.
>0 unanchored
>1 anchored
>0 perl class used
>.alphabeta. .lphabet.
>1 POSIX-mode, should inhibit Perl class
>0 POSIX-mode with Perl classes enabled .lphabet.
>0 matched, set vars
>.alphabeta. 9
>.lph|bet.
>1 unmatched, not setting MATCH/match
>.. 0
>..
m() {
unset MATCH MBEGIN MEND match mbegin mend
[[ $2 -re2-match $3 ]]
print $? $1: m:${MATCH}: ma:${(j:|:)match}: MBEGIN=$MBEGIN MEND=$MEND mbegin="(${mbegin[*]})" mend="(${mend[*]})"
}
data='alpha beta gamma delta'
m uncapturing $data '\b\w+\b'
m capturing $data '\b(\w+)\b'
m 'capture 2' $data '\b(\w+)\s+(\w+)\b'
m 'capture repeat' $data '\b(?:(\w+)\s+)+(\w+)\b'
0:Beginning and end testing
>0 uncapturing: m:alpha: ma:: MBEGIN=1 MEND=5 mbegin=() mend=()
>0 capturing: m:alpha: ma:alpha: MBEGIN=1 MEND=5 mbegin=(1) mend=(5)
>0 capture 2: m:alpha beta: ma:alpha|beta: MBEGIN=1 MEND=10 mbegin=(1 7) mend=(5 10)
>0 capture repeat: m:alpha beta gamma delta: ma:gamma|delta: MBEGIN=1 MEND=22 mbegin=(12 18) mend=(16 22)
unset match mend
s=$'\u00a0'
[[ $s -re2-match '^.$' ]] && print OK
[[ A${s}B -re2-match .(.). && $match[1] == $s ]] && print OK
[[ A${s}${s}B -re2-match A([^[:ascii:]]*)B && $mend[1] == 3 ]] && print OK
unset s
0:Raw IMETA characters in input string
>OK
>OK
>OK
[[ foo -re2-match f.+ ]] ; print $?
[[ foo -re2-match x.+ ]] ; print $?
[[ ! foo -re2-match f.+ ]] ; print $?
[[ ! foo -re2-match x.+ ]] ; print $?
[[ foo -re2-match f.+ && bar -re2-match b.+ ]] ; print $?
[[ foo -re2-match x.+ && bar -re2-match b.+ ]] ; print $?
[[ foo -re2-match f.+ && bar -re2-match x.+ ]] ; print $?
[[ ! foo -re2-match f.+ && bar -re2-match b.+ ]] ; print $?
[[ foo -re2-match f.+ && ! bar -re2-match b.+ ]] ; print $?
[[ ! ( foo -re2-match f.+ && bar -re2-match b.+ ) ]] ; print $?
[[ ! foo -re2-match x.+ && bar -re2-match b.+ ]] ; print $?
[[ foo -re2-match x.+ && ! bar -re2-match b.+ ]] ; print $?
[[ ! ( foo -re2-match x.+ && bar -re2-match b.+ ) ]] ; print $?
0:Regex result inversion detection
>0
>1
>1
>0
>0
>1
>1
>1
>1
>1
>0
>1
>0
# Subshell because crash on failure
( [[ test.txt -re2-match '^(.*_)?(test)' ]]
echo $match[2] )
0:regression for segmentation fault (pcre, dup for re2), workers/38307
>test
setopt BASH_REMATCH KSH_ARRAYS
unset MATCH MBEGIN MEND match mbegin mend BASH_REMATCH
[[ alphabeta -re2-match '^a([^a]+)(a)([^a]+)a$' ]]
echo "$? bash_rematch"
echo "m:${MATCH}: ma:${(j:|:)match}:"
echo MBEGIN=$MBEGIN MEND=$MEND mbegin="(${mbegin[*]})" mend="(${mend[*]})"
echo "BASH_REMATCH=[${(j:, :)BASH_REMATCH[@]}]"
echo "[0]=${BASH_REMATCH[0]} [1]=${BASH_REMATCH[1]}"
0:bash_rematch works
>0 bash_rematch
>m:: ma::
>MBEGIN= MEND= mbegin=() mend=()
>BASH_REMATCH=[alphabeta, lph, a, bet]
>[0]=alphabeta [1]=lph
|