| 1 | ## oils_failures_allowed: 0
 | 
| 2 | ## compare_shells: bash-4.4 zsh
 | 
| 3 | 
 | 
| 4 | #
 | 
| 5 | # Only bash and zsh seem to implement [[ foo =~ '' ]]
 | 
| 6 | #
 | 
| 7 | # ^(a b)$ is a regex that should match 'a b' in a group.
 | 
| 8 | #
 | 
| 9 | # Not sure what bash is doing here... I think I have to just be empirical.
 | 
| 10 | # Might need "compat" switch for parsing the regex.  It should be an opaque
 | 
| 11 | # string like zsh, not sure why it isn't.
 | 
| 12 | #
 | 
| 13 | # I think this is just papering over bugs...
 | 
| 14 | # https://www.gnu.org/software/bash/manual/bash.html#Conditional-Constructs
 | 
| 15 | #
 | 
| 16 | # Storing the regular expression in a shell variable is often a useful way to
 | 
| 17 | # avoid problems with quoting characters that are special to the shell. It is
 | 
| 18 | # sometimes difficult to specify a regular expression literally without using
 | 
| 19 | # quotes, or to keep track of the quoting used by regular expressions while
 | 
| 20 | # paying attention to the shell’s quote removal. Using a shell variable to
 | 
| 21 | # store the pattern decreases these problems. For example, the following is
 | 
| 22 | # equivalent to the above:
 | 
| 23 | #
 | 
| 24 | # pattern='[[:space:]]*(a)?b'
 | 
| 25 | # [[ $line =~ $pattern ]]
 | 
| 26 | # 
 | 
| 27 | # If you want to match a character that’s special to the regular expression
 | 
| 28 | # grammar, it has to be quoted to remove its special meaning. This means that in
 | 
| 29 | # the pattern ‘xxx.txt’, the ‘.’ matches any character in the string (its usual
 | 
| 30 | # regular expression meaning), but in the pattern ‘"xxx.txt"’ it can only match a
 | 
| 31 | # literal ‘.’. Shell programmers should take special care with backslashes, since
 | 
| 32 | # backslashes are used both by the shell and regular expressions to remove the
 | 
| 33 | # special meaning from the following character. The following two sets of
 | 
| 34 | # commands are not equivalent: 
 | 
| 35 | #
 | 
| 36 | # From bash code: ( | ) are treated special.  Normally they must be quoted, but
 | 
| 37 | # they can be UNQUOTED in BASH_REGEX state.  In fact they can't be quoted!
 | 
| 38 | 
 | 
| 39 | #### BASH_REMATCH
 | 
| 40 | [[ foo123 =~ ([a-z]+)([0-9]+) ]]
 | 
| 41 | echo status=$?
 | 
| 42 | argv.py "${BASH_REMATCH[@]}"
 | 
| 43 | 
 | 
| 44 | [[ failed =~ ([a-z]+)([0-9]+) ]]
 | 
| 45 | echo status=$?
 | 
| 46 | argv.py "${BASH_REMATCH[@]}"  # not cleared!
 | 
| 47 | 
 | 
| 48 | ## STDOUT:
 | 
| 49 | status=0
 | 
| 50 | ['foo123', 'foo', '123']
 | 
| 51 | status=1
 | 
| 52 | []
 | 
| 53 | ## END
 | 
| 54 | ## N-I zsh STDOUT:
 | 
| 55 | status=0
 | 
| 56 | ['']
 | 
| 57 | status=1
 | 
| 58 | ['']
 | 
| 59 | ## END
 | 
| 60 | 
 | 
| 61 | #### Match is unanchored at both ends
 | 
| 62 | [[ 'bar' =~ a ]] && echo true
 | 
| 63 | ## stdout: true
 | 
| 64 | 
 | 
| 65 | #### Failed match
 | 
| 66 | [[ 'bar' =~ X ]] && echo true
 | 
| 67 | ## status: 1
 | 
| 68 | ## stdout-json: ""
 | 
| 69 | 
 | 
| 70 | #### Regex quoted with \ -- preferred in bash
 | 
| 71 | [[ 'a b' =~ ^(a\ b)$ ]] && echo true
 | 
| 72 | ## stdout: true
 | 
| 73 | 
 | 
| 74 | #### Regex quoted with single quotes
 | 
| 75 | # bash doesn't like the quotes
 | 
| 76 | [[ 'a b' =~ '^(a b)$' ]] && echo true
 | 
| 77 | ## stdout-json: ""
 | 
| 78 | ## status: 1
 | 
| 79 | ## OK zsh stdout: true
 | 
| 80 | ## OK zsh status: 0
 | 
| 81 | 
 | 
| 82 | #### Regex quoted with double quotes
 | 
| 83 | # bash doesn't like the quotes
 | 
| 84 | [[ 'a b' =~ "^(a b)$" ]] && echo true
 | 
| 85 | ## stdout-json: ""
 | 
| 86 | ## status: 1
 | 
| 87 | ## OK zsh stdout: true
 | 
| 88 | ## OK zsh status: 0
 | 
| 89 | 
 | 
| 90 | #### Fix single quotes by storing in variable
 | 
| 91 | pat='^(a b)$'
 | 
| 92 | [[ 'a b' =~ $pat ]] && echo true
 | 
| 93 | ## stdout: true
 | 
| 94 | 
 | 
| 95 | #### Fix single quotes by storing in variable
 | 
| 96 | pat="^(a b)$"
 | 
| 97 | [[ 'a b' =~ $pat ]] && echo true
 | 
| 98 | ## stdout: true
 | 
| 99 | 
 | 
| 100 | #### Double quoting pat variable -- again bash doesn't like it.
 | 
| 101 | pat="^(a b)$"
 | 
| 102 | [[ 'a b' =~ "$pat" ]] && echo true
 | 
| 103 | ## stdout-json: ""
 | 
| 104 | ## status: 1
 | 
| 105 | ## OK zsh stdout: true
 | 
| 106 | ## OK zsh status: 0
 | 
| 107 | 
 | 
| 108 | #### Mixing quoted and unquoted parts
 | 
| 109 | [[ 'a b' =~ 'a 'b ]] && echo true
 | 
| 110 | [[ "a b" =~ "a "'b' ]] && echo true
 | 
| 111 | ## STDOUT:
 | 
| 112 | true
 | 
| 113 | true
 | 
| 114 | ## END
 | 
| 115 | 
 | 
| 116 | #### Regex with == and not =~ is parse error, different lexer mode required
 | 
| 117 | # They both give a syntax error.  This is lame.
 | 
| 118 | [[ '^(a b)$' == ^(a\ b)$ ]] && echo true
 | 
| 119 | ## status: 2
 | 
| 120 | ## OK zsh status: 1
 | 
| 121 | 
 | 
| 122 | #### Omitting ( )
 | 
| 123 | [[ '^a b$' == ^a\ b$ ]] && echo true
 | 
| 124 | ## stdout: true
 | 
| 125 | 
 | 
| 126 | #### Malformed regex
 | 
| 127 | # Are they trying to PARSE the regex?  Do they feed the buffer directly to
 | 
| 128 | # regcomp()?
 | 
| 129 | [[ 'a b' =~ ^)a\ b($ ]] && echo true
 | 
| 130 | ## stdout-json: ""
 | 
| 131 | ## status: 2
 | 
| 132 | ## OK zsh status: 1
 | 
| 133 | 
 | 
| 134 | #### Regex with |
 | 
| 135 | [[ 'bar' =~ foo|bar ]] && echo true
 | 
| 136 | ## stdout: true
 | 
| 137 | ## N-I zsh stdout-json: ""
 | 
| 138 | ## N-I zsh status: 1
 | 
| 139 | 
 | 
| 140 | #### Regex to match literal brackets []
 | 
| 141 | 
 | 
| 142 | # bash-completion relies on this, so we're making it match bash.
 | 
| 143 | # zsh understandably differs.
 | 
| 144 | [[ '[]' =~ \[\] ]] && echo true
 | 
| 145 | 
 | 
| 146 | # Another way to write this.
 | 
| 147 | pat='\[\]'
 | 
| 148 | [[ '[]' =~ $pat ]] && echo true
 | 
| 149 | ## STDOUT:
 | 
| 150 | true
 | 
| 151 | true
 | 
| 152 | ## END
 | 
| 153 | ## OK zsh STDOUT:
 | 
| 154 | true
 | 
| 155 | ## END
 | 
| 156 | 
 | 
| 157 | #### Regex to match literals . ^ $ etc.
 | 
| 158 | [[ 'x' =~ \. ]] || echo false
 | 
| 159 | [[ '.' =~ \. ]] && echo true
 | 
| 160 | 
 | 
| 161 | [[ 'xx' =~ \^\$ ]] || echo false
 | 
| 162 | [[ '^$' =~ \^\$ ]] && echo true
 | 
| 163 | 
 | 
| 164 | [[ 'xxx' =~ \+\*\? ]] || echo false
 | 
| 165 | [[ '*+?' =~ \*\+\? ]] && echo true
 | 
| 166 | 
 | 
| 167 | [[ 'xx' =~ \{\} ]] || echo false
 | 
| 168 | [[ '{}' =~ \{\} ]] && echo true
 | 
| 169 | ## STDOUT:
 | 
| 170 | false
 | 
| 171 | true
 | 
| 172 | false
 | 
| 173 | true
 | 
| 174 | false
 | 
| 175 | true
 | 
| 176 | false
 | 
| 177 | true
 | 
| 178 | ## END
 | 
| 179 | ## BUG zsh STDOUT:
 | 
| 180 | true
 | 
| 181 | false
 | 
| 182 | false
 | 
| 183 | false
 | 
| 184 | ## END
 | 
| 185 | ## BUG zsh status: 1
 | 
| 186 | 
 | 
| 187 | #### Unquoted { is a regex parse error
 | 
| 188 | [[ { =~ { ]] && echo true
 | 
| 189 | echo status=$?
 | 
| 190 | ## stdout-json: ""
 | 
| 191 | ## status: 2
 | 
| 192 | ## BUG bash stdout-json: "status=2\n"
 | 
| 193 | ## BUG bash status: 0
 | 
| 194 | ## BUG zsh stdout-json: "status=1\n"
 | 
| 195 | ## BUG zsh status: 0
 | 
| 196 | 
 | 
| 197 | #### Fatal error inside [[ =~ ]]
 | 
| 198 | 
 | 
| 199 | # zsh and osh are stricter than bash.  bash treats [[ like a command.
 | 
| 200 | 
 | 
| 201 | [[ a =~ $(( 1 / 0 )) ]]
 | 
| 202 | echo status=$?
 | 
| 203 | ## stdout-json: ""
 | 
| 204 | ## status: 1
 | 
| 205 | ## BUG bash stdout: status=1
 | 
| 206 | ## BUG bash status: 0
 | 
| 207 | 
 | 
| 208 | #### Quoted { and +
 | 
| 209 | [[ { =~ "{" ]] && echo 'yes {'
 | 
| 210 | [[ + =~ "+" ]] && echo 'yes +'
 | 
| 211 | [[ * =~ "*" ]] && echo 'yes *'
 | 
| 212 | [[ ? =~ "?" ]] && echo 'yes ?'
 | 
| 213 | [[ ^ =~ "^" ]] && echo 'yes ^'
 | 
| 214 | [[ $ =~ "$" ]] && echo 'yes $'
 | 
| 215 | [[ '(' =~ '(' ]] && echo 'yes ('
 | 
| 216 | [[ ')' =~ ')' ]] && echo 'yes )'
 | 
| 217 | [[ '|' =~ '|' ]] && echo 'yes |'
 | 
| 218 | [[ '\' =~ '\' ]] && echo 'yes \'
 | 
| 219 | echo ---
 | 
| 220 | 
 | 
| 221 | [[ . =~ "." ]] && echo 'yes .'
 | 
| 222 | [[ z =~ "." ]] || echo 'no .'
 | 
| 223 | echo ---
 | 
| 224 | 
 | 
| 225 | # This rule is weird but all shells agree.  I would expect that the - gets
 | 
| 226 | # escaped?  It's an operator?  but it behaves like a-z.
 | 
| 227 | [[ a =~ ["a-z"] ]]; echo "a $?"
 | 
| 228 | [[ - =~ ["a-z"] ]]; echo "- $?"
 | 
| 229 | [[ b =~ ['a-z'] ]]; echo "b $?"
 | 
| 230 | [[ z =~ ['a-z'] ]]; echo "z $?"
 | 
| 231 | 
 | 
| 232 | echo status=$?
 | 
| 233 | ## STDOUT:
 | 
| 234 | yes {
 | 
| 235 | yes +
 | 
| 236 | yes *
 | 
| 237 | yes ?
 | 
| 238 | yes ^
 | 
| 239 | yes $
 | 
| 240 | yes (
 | 
| 241 | yes )
 | 
| 242 | yes |
 | 
| 243 | yes \
 | 
| 244 | ---
 | 
| 245 | yes .
 | 
| 246 | no .
 | 
| 247 | ---
 | 
| 248 | a 0
 | 
| 249 | - 1
 | 
| 250 | b 0
 | 
| 251 | z 0
 | 
| 252 | status=0
 | 
| 253 | ## END
 | 
| 254 | ## N-I zsh STDOUT:
 | 
| 255 | yes ^
 | 
| 256 | yes $
 | 
| 257 | yes )
 | 
| 258 | yes |
 | 
| 259 | ---
 | 
| 260 | yes .
 | 
| 261 | ---
 | 
| 262 | a 0
 | 
| 263 | - 1
 | 
| 264 | b 0
 | 
| 265 | z 0
 | 
| 266 | status=0
 | 
| 267 | ## END
 | 
| 268 | 
 | 
| 269 | #### Escaped {
 | 
| 270 | # from bash-completion
 | 
| 271 | [[ '$PA' =~ ^(\$\{?)([A-Za-z0-9_]*)$ ]] && argv.py "${BASH_REMATCH[@]}"
 | 
| 272 | ## STDOUT:
 | 
| 273 | ['$PA', '$', 'PA']
 | 
| 274 | ## END
 | 
| 275 | ## BUG zsh stdout-json: ""
 | 
| 276 | ## BUG zsh status: 1
 | 
| 277 | 
 | 
| 278 | #### Escaped { stored in variable first
 | 
| 279 | # from bash-completion
 | 
| 280 | pat='^(\$\{?)([A-Za-z0-9_]*)$'
 | 
| 281 | [[ '$PA' =~ $pat ]] && argv.py "${BASH_REMATCH[@]}"
 | 
| 282 | ## STDOUT:
 | 
| 283 | ['$PA', '$', 'PA']
 | 
| 284 | ## END
 | 
| 285 | ## BUG zsh STDOUT:
 | 
| 286 | ['']
 | 
| 287 | ## END
 | 
| 288 | 
 | 
| 289 | #### regex with ?
 | 
| 290 | [[ 'c' =~ c? ]] && echo true
 | 
| 291 | [[ '' =~ c? ]] && echo true
 | 
| 292 | ## STDOUT:
 | 
| 293 | true
 | 
| 294 | true
 | 
| 295 | ## END
 | 
| 296 | 
 | 
| 297 | #### regex with unprintable characters
 | 
| 298 | # can't have nul byte
 | 
| 299 | 
 | 
| 300 | # This pattern has literal characters
 | 
| 301 | pat=$'^[\x01\x02]+$'
 | 
| 302 | 
 | 
| 303 | [[ $'\x01\x02\x01' =~ $pat ]]; echo status=$?
 | 
| 304 | [[ $'a\x01' =~ $pat ]]; echo status=$?
 | 
| 305 | 
 | 
| 306 | # NOTE: There doesn't appear to be any way to escape these!
 | 
| 307 | pat2='^[\x01\x02]+$'
 | 
| 308 | 
 | 
| 309 | ## STDOUT:
 | 
| 310 | status=0
 | 
| 311 | status=1
 | 
| 312 | ## END
 | 
| 313 | 
 | 
| 314 | #### pattern $f(x)  -- regression
 | 
| 315 | f=fff
 | 
| 316 | [[ fffx =~ $f(x) ]]
 | 
| 317 | echo status=$?
 | 
| 318 | [[ ffx =~ $f(x) ]]
 | 
| 319 | echo status=$?
 | 
| 320 | ## STDOUT:
 | 
| 321 | status=0
 | 
| 322 | status=1
 | 
| 323 | ## END
 | 
| 324 | 
 | 
| 325 | #### pattern a=(1) 
 | 
| 326 | [[ a=x =~ a=(x) ]]
 | 
| 327 | echo status=$?
 | 
| 328 | [[ =x =~ a=(x) ]]
 | 
| 329 | echo status=$?
 | 
| 330 | ## STDOUT:
 | 
| 331 | status=0
 | 
| 332 | status=1
 | 
| 333 | ## END
 | 
| 334 | ## BUG zsh status: 1
 | 
| 335 | ## BUG zsh STDOUT:
 | 
| 336 | status=0
 | 
| 337 | ## END
 | 
| 338 | 
 | 
| 339 | #### pattern @f(x)
 | 
| 340 | shopt -s parse_at
 | 
| 341 | [[ @fx =~ @f(x) ]]
 | 
| 342 | echo status=$?
 | 
| 343 | [[ fx =~ @f(x) ]]
 | 
| 344 | echo status=$?
 | 
| 345 | ## STDOUT:
 | 
| 346 | status=0
 | 
| 347 | status=1
 | 
| 348 | ## END
 | 
| 349 | 
 | 
| 350 | 
 | 
| 351 | #### Bug: Nix idiom with closing ) next to pattern
 | 
| 352 | 
 | 
| 353 | if [[ ! (" ${params[*]} " =~ " -shared " || " ${params[*]} " =~ " -static ") ]]; then
 | 
| 354 |   echo one
 | 
| 355 | fi
 | 
| 356 | 
 | 
| 357 | # Reduced idiom
 | 
| 358 | if [[ (foo =~ foo) ]]; then
 | 
| 359 |   echo two
 | 
| 360 | fi
 | 
| 361 | 
 | 
| 362 | ## STDOUT:
 | 
| 363 | one
 | 
| 364 | two
 | 
| 365 | ## END
 | 
| 366 | 
 | 
| 367 | #### unquoted (a  b) as pattern, (a  b|c)
 | 
| 368 | 
 | 
| 369 | if [[ 'a  b' =~ (a  b) ]]; then
 | 
| 370 |   echo one
 | 
| 371 | fi
 | 
| 372 | 
 | 
| 373 | if [[ 'a b' =~ (a  b) ]]; then
 | 
| 374 |   echo BAD
 | 
| 375 | fi
 | 
| 376 | 
 | 
| 377 | if [[ 'a b' =~ (a b|c) ]]; then
 | 
| 378 |   echo two
 | 
| 379 | fi
 | 
| 380 | 
 | 
| 381 | # I think spaces are only allowed within ()
 | 
| 382 | 
 | 
| 383 | if [[ '  c' =~ (a|  c) ]]; then
 | 
| 384 |   echo three
 | 
| 385 | fi
 | 
| 386 | 
 | 
| 387 | ## STDOUT:
 | 
| 388 | one
 | 
| 389 | two
 | 
| 390 | three
 | 
| 391 | ## END
 | 
| 392 | 
 | 
| 393 | #### Multiple adjacent () groups
 | 
| 394 | 
 | 
| 395 | if [[ 'a-b-c-d' =~ a-(b|  >>)-c-( ;|[de])|ff|gg ]]; then
 | 
| 396 |   argv.py "${BASH_REMATCH[@]}"
 | 
| 397 | fi
 | 
| 398 | 
 | 
| 399 | if [[ ff =~ a-(b|  >>)-c-( ;|[de])|ff|gg ]]; then
 | 
| 400 |   argv.py "${BASH_REMATCH[@]}"
 | 
| 401 | fi
 | 
| 402 | 
 | 
| 403 | # empty group ()
 | 
| 404 | 
 | 
| 405 | if [[ zz =~ ([a-z]+)() ]]; then
 | 
| 406 |   argv.py "${BASH_REMATCH[@]}"
 | 
| 407 | fi
 | 
| 408 | 
 | 
| 409 | # nested empty group
 | 
| 410 | if [[ zz =~ ([a-z]+)(()z) ]]; then
 | 
| 411 |   argv.py "${BASH_REMATCH[@]}"
 | 
| 412 | fi
 | 
| 413 | 
 | 
| 414 | ## STDOUT:
 | 
| 415 | ['a-b-c-d', 'b', 'd']
 | 
| 416 | ['ff', '', '']
 | 
| 417 | ['zz', 'zz', '']
 | 
| 418 | ['zz', 'z', 'z', '']
 | 
| 419 | ## END
 | 
| 420 | 
 | 
| 421 | ## BUG zsh status: 1
 | 
| 422 | ## BUG zsh STDOUT:
 | 
| 423 | ['']
 | 
| 424 | ['']
 | 
| 425 | ['']
 | 
| 426 | ['']
 | 
| 427 | ## END
 | 
| 428 | 
 | 
| 429 | #### unquoted [a  b] as pattern, [a  b|c]
 | 
| 430 | 
 | 
| 431 | $SH <<'EOF'
 | 
| 432 | [[ a =~ [ab] ]] && echo yes
 | 
| 433 | EOF
 | 
| 434 | echo "[ab]=$?"
 | 
| 435 | 
 | 
| 436 | $SH <<'EOF'
 | 
| 437 | [[ a =~ [a b] ]] && echo yes
 | 
| 438 | EOF
 | 
| 439 | echo "[a b]=$?"
 | 
| 440 | 
 | 
| 441 | $SH <<'EOF'
 | 
| 442 | [[ a =~ ([a b]) ]] && echo yes
 | 
| 443 | EOF
 | 
| 444 | echo "[a b]=$?"
 | 
| 445 | 
 | 
| 446 | ## STDOUT:
 | 
| 447 | yes
 | 
| 448 | [ab]=0
 | 
| 449 | [a b]=2
 | 
| 450 | yes
 | 
| 451 | [a b]=0
 | 
| 452 | ## END
 | 
| 453 | 
 | 
| 454 | ## OK zsh STDOUT:
 | 
| 455 | yes
 | 
| 456 | [ab]=0
 | 
| 457 | [a b]=1
 | 
| 458 | yes
 | 
| 459 | [a b]=0
 | 
| 460 | ## END
 | 
| 461 | 
 | 
| 462 | #### c|a unquoted
 | 
| 463 | 
 | 
| 464 | if [[ a =~ c|a ]]; then
 | 
| 465 |   echo one
 | 
| 466 | fi
 | 
| 467 | 
 | 
| 468 | ## STDOUT:
 | 
| 469 | one
 | 
| 470 | ## END
 | 
| 471 | ## N-I zsh status: 1
 | 
| 472 | 
 | 
| 473 | #### Operator chars ; & but not |
 | 
| 474 | 
 | 
| 475 | # Hm semicolon is still an operator in bash
 | 
| 476 | $SH <<'EOF'
 | 
| 477 | [[ ';' =~ ; ]] && echo semi
 | 
| 478 | EOF
 | 
| 479 | echo semi=$?
 | 
| 480 | 
 | 
| 481 | $SH <<'EOF'
 | 
| 482 | [[ ';' =~ (;) ]] && echo semi paren
 | 
| 483 | EOF
 | 
| 484 | echo semi paren=$?
 | 
| 485 | 
 | 
| 486 | echo
 | 
| 487 | 
 | 
| 488 | $SH <<'EOF'
 | 
| 489 | [[ '&' =~ & ]] && echo amp
 | 
| 490 | EOF
 | 
| 491 | echo amp=$?
 | 
| 492 | 
 | 
| 493 | # Oh I guess this is not a bug?  regcomp doesn't reject this trivial regex?
 | 
| 494 | $SH <<'EOF'
 | 
| 495 | [[ '|' =~ | ]] && echo pipe1
 | 
| 496 | [[ 'a' =~ | ]] && echo pipe2
 | 
| 497 | EOF
 | 
| 498 | echo pipe=$?
 | 
| 499 | 
 | 
| 500 | $SH <<'EOF'
 | 
| 501 | [[ '|' =~ a| ]] && echo four
 | 
| 502 | EOF
 | 
| 503 | echo pipe=$?
 | 
| 504 | 
 | 
| 505 | # This is probably special because > operator is inside foo [[ a > b ]]
 | 
| 506 | $SH <<'EOF'
 | 
| 507 | [[ '<>' =~ <> ]] && echo angle
 | 
| 508 | EOF
 | 
| 509 | echo angle=$?
 | 
| 510 | 
 | 
| 511 | # Bug: OSH allowed this!
 | 
| 512 | $SH <<'EOF'
 | 
| 513 | [[ $'a\nb' =~ a
 | 
| 514 | b ]] && echo newline
 | 
| 515 | EOF
 | 
| 516 | echo newline=$?
 | 
| 517 | 
 | 
| 518 | ## STDOUT:
 | 
| 519 | semi=2
 | 
| 520 | semi paren
 | 
| 521 | semi paren=0
 | 
| 522 | 
 | 
| 523 | amp=2
 | 
| 524 | pipe1
 | 
| 525 | pipe2
 | 
| 526 | pipe=0
 | 
| 527 | four
 | 
| 528 | pipe=0
 | 
| 529 | angle=2
 | 
| 530 | newline=2
 | 
| 531 | ## END
 | 
| 532 | 
 | 
| 533 | ## BUG zsh STDOUT:
 | 
| 534 | semi=1
 | 
| 535 | semi paren=1
 | 
| 536 | 
 | 
| 537 | amp=1
 | 
| 538 | pipe=1
 | 
| 539 | pipe=1
 | 
| 540 | angle=1
 | 
| 541 | newline=1
 | 
| 542 | ## END
 | 
| 543 | 
 | 
| 544 | 
 | 
| 545 | 
 | 
| 546 | #### Quotes '' "" $'' $"" in pattern
 | 
| 547 | 
 | 
| 548 | $SH <<'EOF'
 | 
| 549 | [[ '|' =~ '|' ]] && echo sq
 | 
| 550 | EOF
 | 
| 551 | echo sq=$?
 | 
| 552 | 
 | 
| 553 | $SH <<'EOF'
 | 
| 554 | [[ '|' =~ "|" ]] && echo dq
 | 
| 555 | EOF
 | 
| 556 | echo dq=$?
 | 
| 557 | 
 | 
| 558 | $SH <<'EOF'
 | 
| 559 | [[ '|' =~ $'|' ]] && echo dollar-sq
 | 
| 560 | EOF
 | 
| 561 | echo dollar-sq=$?
 | 
| 562 | 
 | 
| 563 | $SH <<'EOF'
 | 
| 564 | [[ '|' =~ $"|" ]] && echo dollar-dq
 | 
| 565 | EOF
 | 
| 566 | echo dollar-dq=$?
 | 
| 567 | 
 | 
| 568 | ## STDOUT:
 | 
| 569 | sq
 | 
| 570 | sq=0
 | 
| 571 | dq
 | 
| 572 | dq=0
 | 
| 573 | dollar-sq
 | 
| 574 | dollar-sq=0
 | 
| 575 | dollar-dq
 | 
| 576 | dollar-dq=0
 | 
| 577 | ## END
 | 
| 578 | 
 | 
| 579 | 
 | 
| 580 | #### Unicode in pattern
 | 
| 581 | 
 | 
| 582 | $SH <<'EOF'
 | 
| 583 | [[ μ =~ μ ]] && echo mu
 | 
| 584 | EOF
 | 
| 585 | echo mu=$?
 | 
| 586 | 
 | 
| 587 | ## STDOUT:
 | 
| 588 | mu
 | 
| 589 | mu=0
 | 
| 590 | ## END
 | 
| 591 | 
 | 
| 592 | #### Parse error with 2 words
 | 
| 593 | 
 | 
| 594 | if [[ a =~ c a ]]; then
 | 
| 595 |   echo one
 | 
| 596 | fi
 | 
| 597 | 
 | 
| 598 | ## status: 2
 | 
| 599 | ## STDOUT:
 | 
| 600 | ## END
 | 
| 601 | 
 | 
| 602 | ## BUG zsh status: 1
 | 
| 603 | ## BUG zsh STDOUT:
 | 
| 604 | one
 | 
| 605 | ## END
 | 
| 606 | 
 | 
| 607 | #### make a lisp example
 | 
| 608 | 
 | 
| 609 | str='(hi)'
 | 
| 610 | [[ "${str}" =~ ^^([][{}\(\)^@])|^(~@)|(\"(\\.|[^\\\"])*\")|^(;[^$'\n']*)|^([~\'\`])|^([^][ ~\`\'\";{}\(\)^@\,]+)|^[,]|^[[:space:]]+ ]]
 | 
| 611 | echo status=$?
 | 
| 612 | 
 | 
| 613 | m=${BASH_REMATCH[0]}
 | 
| 614 | echo m=$m
 | 
| 615 | 
 | 
| 616 | ## STDOUT:
 | 
| 617 | status=0
 | 
| 618 | m=(
 | 
| 619 | ## END
 | 
| 620 | 
 | 
| 621 | ## BUG zsh STDOUT:
 | 
| 622 | status=1
 | 
| 623 | m=
 | 
| 624 | ## END
 | 
| 625 | 
 | 
| 626 | #### Operators and space lose meaning inside ()
 | 
| 627 | [[ '< >' =~ (< >) ]] && echo true
 | 
| 628 | ## stdout: true
 | 
| 629 | ## N-I zsh stdout-json: ""
 | 
| 630 | ## N-I zsh status: 1
 | 
| 631 | 
 |