1 # Test out Oil's regular expression syntax.
2
3 #### /^.$/
4 shopt -s oil:all
5 var pat = ''
6
7 setvar pat = /^.$/
8 echo pat=$pat
9
10 setvar pat = /%start dot %end/
11 echo pat=$pat
12
13 if ('' ~ pat) { # ERE syntax
14 echo yes
15 } else {
16 echo no
17 }
18 # $pat is same as pat
19 if ('f' ~ pat) { # ERE syntax
20 echo yes
21 } else {
22 echo no
23 }
24
25 ## STDOUT:
26 pat=^.$
27 pat=^.$
28 no
29 yes
30 ## END
31
32
33 #### /.+/
34 shopt -s oil:all
35
36 var pat = /.+/
37 echo $pat
38
39 var s = 'foo'
40 if (s ~ pat) { # ERE syntax
41 echo yes
42 }
43 var empty = ''
44 if (empty ~ pat) { echo yes } else { echo no }
45 ## STDOUT:
46 .+
47 yes
48 no
49 ## END
50
51 #### Repeat {1,3} etc.
52 var pat = null
53
54 setvar pat = /d{2}/
55 echo $pat
56 setvar pat = /d{1,3}/
57 echo $pat
58 setvar pat = /d{1,}/
59 echo $pat
60 setvar pat = /d{,3}/
61 echo $pat
62
63
64 ## STDOUT:
65 [[:digit:]]{2}
66 [[:digit:]]{1,3}
67 [[:digit:]]{1,}
68 [[:digit:]]{,3}
69 ## END
70
71
72 #### d+ digit+ ~d+ ~digit+
73 shopt -s oil:all
74
75 var pat = ''
76
77 setvar pat = /d+/
78 echo $pat
79 if ('42' ~ pat) { echo yes }
80
81 var empty = ''
82 if (empty ~ pat) { echo yes } else { echo no }
83
84 setvar pat = /digit+/
85 echo $pat
86 setvar pat = /~d+/
87 echo $pat
88 setvar pat = /~digit+/
89 echo $pat
90
91
92 ## STDOUT:
93 [[:digit:]]+
94 yes
95 no
96 [[:digit:]]+
97 [^[:digit:]]+
98 [^[:digit:]]+
99 ## END
100
101 #### Alternation and sequence
102 var pat = ''
103 setvar pat = /s d+ | w*/
104 echo $pat
105 setvar pat = /s d+ or w*/
106 echo $pat
107 ## STDOUT:
108 [[:space:]][[:digit:]]+|[[:alpha:][:digit:]_]*
109 [[:space:]][[:digit:]]+|[[:alpha:][:digit:]_]*
110 ## END
111
112 #### Char Class Ranges
113 shopt -s oil:all
114
115 var pat = ''
116 setvar pat = /[0-9 a-f]+/
117 echo $pat
118 # This is equivalent
119 setvar pat = /['0' - '9' 'a' - 'f']+/
120 echo $pat
121
122 if ('0123' ~ pat) { echo yes } else { echo no }
123 if ('zzz' ~ pat) { echo yes } else { echo no }
124 if ('' ~ pat) { echo yes } else { echo no }
125 ## STDOUT:
126 [0-9a-f]+
127 [0-9a-f]+
128 yes
129 no
130 no
131 ## END
132
133 #### Char Class Set
134 shopt -s oil:all
135 var pat = ''
136
137 # This is NOT allowed
138 # setvar pat = /[a b c]+/
139
140 setvar pat = /['abc']+/
141 echo $pat
142
143 if ('cbcb' ~ pat) { echo yes } else { echo no }
144 if ('0123' ~ pat) { echo yes } else { echo no }
145 if ('' ~ pat) { echo yes } else { echo no }
146 ## STDOUT:
147 [abc]+
148 yes
149 no
150 no
151 ## END
152
153 #### Range with escaped characters
154 shopt -s oil:all
155
156 var pat = null
157
158 setvar pat = / [ \x00 - \x0f ] /
159 echo $pat | od -A n -t x1
160
161 ## STDOUT:
162 5b 00 2d 0f 5d 0a
163 ## END
164
165
166 #### Group ()
167 shopt -s oil:all
168 var pat = ''
169
170 setvar pat = /(%start s or d d)/
171 echo $pat
172
173 if (' foo' ~ pat) { echo yes } else { echo no }
174 if ('-00-' ~ pat) { echo yes } else { echo no }
175 if ('foo' ~ pat) { echo yes } else { echo no }
176
177 ## STDOUT:
178 (^[[:space:]]|[[:digit:]][[:digit:]])
179 yes
180 yes
181 no
182 ## END
183
184
185 #### literal ''
186 shopt -s oil:all
187 var pat = ''
188
189 setvar pat = /'abc' 'def'/
190 echo $pat
191
192 #setvar pat = /'abc' '^ + * ?'/
193 #echo $pat
194
195 if ('abcde' ~ pat) { echo yes } else { echo no }
196 if ('abcdef' ~ pat) { echo yes } else { echo no }
197
198 ## STDOUT:
199 abcdef
200 no
201 yes
202 ## END
203
204 #### double quoted, $x, and ${x}
205 shopt -s oil:all
206 var pat = ''
207
208 var x = 'x'
209 var y = 'y'
210 setvar pat = / $x ${x} "abc" "$x${y}"/
211 echo $pat
212
213 if ('xxabcx' ~ pat) { echo yes } else { echo no }
214 if ('xxabcxyf' ~ pat) { echo yes } else { echo no }
215
216 ## STDOUT:
217 xxabcxy
218 no
219 yes
220 ## END
221
222 #### @splice
223 shopt -s oil:all
224 var d = /d+/;
225 var ip = / @d '.' @d '.' @d '.' @d /
226 echo $ip
227 if ('0.0.0.0' ~ ip) { echo yes } else { echo no }
228 if ('0.0.0' ~ ip) { echo yes } else { echo no }
229 ## STDOUT:
230 [[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+\.[[:digit:]]+
231 yes
232 no
233 ## END
234
235 #### Matching escaped tab character
236 shopt -s oil:all
237
238 # BUG: need C strings in array literal
239 var lines=@($'aa\tbb' $'cc\tdd')
240
241 var pat = / ('a' [\t] 'b') /
242 echo pat=$pat
243 echo @lines | egrep $pat
244
245 ## stdout-json: "pat=(a[\t]b)\naa\tbb\n"
246
247 #### Match non-ASCII byte denoted using c'\xff'
248 shopt -s oil:all
249 var pat = /[ c'\xff' ]/;
250
251 echo $pat | od -A n -t x1
252 if (c'\xff' ~ pat) { echo yes } else { echo no }
253 if (c'\xfe' ~ pat) { echo yes } else { echo no }
254
255 ## STDOUT:
256 5b ff 5d 0a
257 yes
258 no
259 ## END
260
261 #### Match non-ASCII byte denoted using \xff
262 shopt -s oil:all
263 var pat = /[ \xff ]/;
264
265 echo $pat | od -A n -t x1
266 if (c'\xff' ~ pat) { echo yes } else { echo no }
267 if (c'\xfe' ~ pat) { echo yes } else { echo no }
268
269 ## STDOUT:
270 5b ff 5d 0a
271 yes
272 no
273 ## END
274
275 #### ERE can express Unicode escapes that are in the ASCII range
276 shopt -s oil:all
277 var pat = /[ \u007f ]/;
278
279 echo $pat | od -A n -t x1
280 if (c'\x7f' ~ pat) { echo yes } else { echo no }
281 if (c'\x7e' ~ pat) { echo yes } else { echo no }
282
283 ## STDOUT:
284 5b 7f 5d 0a
285 yes
286 no
287 ## END
288
289 #### ERE can't express higher Unicode escapes
290 shopt -s oil:all
291 var pat = /[ \u00ff ]/;
292
293 echo $pat | od -A n -t x1
294 if (c'\x7f' ~ pat) { echo yes } else { echo no }
295 if (c'\x7e' ~ pat) { echo yes } else { echo no }
296
297 ## status: 1
298 ## stdout-json: ""
299
300 #### non-ASCII bytes must be singleton terms, e.g. '\x7f\xff' is disallowed
301 var bytes = c'\x7f\xff'
302 var pat = / [ $bytes ] /
303 echo $pat
304 ## status: 1
305 ## stdout-json: ""
306
307 #### Matching escaped tab character
308 shopt -s oil:all
309
310 # BUG: need C strings in array literal
311 var lines=@($'aa\tbb' $'cc\tdd')
312
313 var pat = / ('a' [\t] 'b') /
314 echo pat=$pat
315 echo @lines | egrep $pat
316
317 ## stdout-json: "pat=(a[\t]b)\naa\tbb\n"
318
319 #### Matching ] and \ and ' and " in character classes
320 shopt -s oil:all
321
322 # BUG: need C strings in array literal
323 var lines=@(
324 'backslash \'
325 'rbracket ]'
326 'lbracket ['
327 "sq '"
328 'dq "'
329 )
330
331 # Weird GNU quirk: ] has to come first!
332 # []abc] works. But [abc\]] does NOT work. Stupid rule!
333
334 var pat = / [ ']' \\ \' \" ] /
335 echo pat=$pat
336 echo @lines | egrep $pat
337
338 ## STDOUT:
339 pat=[]\\'"]
340 backslash \
341 rbracket ]
342 sq '
343 dq "
344 ## END
345
346 #### Matching literal hyphen in character classes
347 shopt -s oil:all
348
349 var literal = '-'
350 var pat = / [ 'a' $literal 'b' ${literal} "-" ] /
351 echo pat=$pat
352 echo 'c-d' 'ab' 'cd' | grep $pat
353 ## STDOUT:
354 pat=[a\-b\-\-]
355 c-d
356 ab
357 ## END
358
359 #### Repeated String Literal With Single Char
360 shopt -s oil:all
361
362 var literal = 'f'
363 var pat = null
364
365 setvar pat = / %start $literal+ %end /
366 echo $pat
367 setvar pat = / %start ($literal)+ %end /
368 echo $pat
369
370 if ('fff' ~ pat) { echo yes }
371 if ('foo' !~ pat) { echo no }
372
373 ## STDOUT:
374 ^f+$
375 ^(f)+$
376 yes
377 no
378 ## END
379
380 #### Error when unparenthesized string of more than one character is repeated
381 shopt -s oil:all
382
383 var literal = 'foo'
384 var pat = null
385
386 setvar pat = / %start $literal+ %end /
387 echo $pat
388 setvar pat = / %start ($literal)+ %end /
389 echo $pat
390
391 if ('foofoo' ~ pat) { echo yes }
392 if ('foof' !~ pat) { echo no }
393
394 ## status: 1
395 ## stdout-json: ""
396
397 #### Instead of c'foo\\bar' use 'foo' \\ 'bar'
398 shopt -s oil:all
399 var pat = /'foo' \\ 'bar'/
400 echo $pat
401
402 if (r'foo\bar' ~ pat) { echo yes }
403 if (r'foo.bar' !~ pat) { echo no }
404 ## STDOUT:
405 foo\\bar
406 yes
407 no
408 ## END
409
410 #### Negation of Character Class
411 shopt -s oil:all
412
413 var pat = / ~[ a-z ] /
414 echo $pat
415
416 if ('0' ~ pat) { echo yes }
417 if ('a' !~ pat) { echo no }
418
419 ## STDOUT:
420 [^a-z]
421 yes
422 no
423 ## END
424
425 #### Posix and Perl class in class literals
426 shopt -s oil:all
427
428 var pat = null
429
430 setvar pat = / [ s 'z' ] /
431 echo $pat
432 #setvar pat = / [ ~s 'z' ] /
433 #echo $pat
434
435 # PROBLEM: can't negate individual POSIX classes. They would have to be a Perl
436 # class to be \D or \S.
437 # [[:space:]z] negates the whole thing!
438 # [^[:space:]]
439
440 setvar pat = / [ digit 'z' ] /
441 echo $pat
442 #setvar pat = / [ ~digit 'z' ] /
443 #echo $pat
444
445 ## STDOUT:
446 [[:space:]z]
447 [[:digit:]z]
448 ## END
449
450 #### Individual Perl and POSIX Classes In Literals Can't Be Negated
451 var pat = null
452 setvar pat = / [ ~d 'z' ] /
453 echo $pat
454 setvar pat = / [ ~digit 'z' ] /
455 echo $pat
456 ## status: 1
457 ## stdout-json: ""