Try this? Works for any value of $1 except when 1=""
arr=( ${(M)arr%%*/[^/]#${1}[^/]#/} )
Full example:
#!/usr/bin/env zsh
# array-filtering.zsh
setopt localoptions extended_glob
test_dir_array_submatch() {
local -a arr=( /dira/${1}/dirb/ /dirc/A${1}B/dird/ /dire/${1}/ /dirf/C${1}D/ )
# works for all values of $1 except ""
print -- ${(M)arr%%*/[^/]#${1}[^/]#/}
}
test_dir_array_submatch Z
test_dir_array_submatch AAA
test_dir_array_submatch AB
test_dir_array_submatch 1
test_dir_array_submatch ""
Outputs:
/dire/Z/ /dirf/CZD/
/dire/AAA/ /dirf/CAAAD/
/dire/AB/ /dirf/CABD/
/dire/1/ /dirf/C1D/
/dira//dirb/ /dirc/AB/dird/ /dire// /dirf/CD/
- Rick
I'm getting better at various filterings
but this one eludes me:
arr=( /dira/${1}/dirb/ /dirc/A${1}B/dird/ /dire/${1}/
/dirf/C${1}D/ )
... it's pretty fussy, but I want to filter out the first and
second elements. The test is that for a list of directories, for
an element to be retained the argument ($1) may be an exact
directory name, or a partial directory name, but it must be the
last directory. Not sure if I'm expressing that correctly. No
subdirectories may follow the matched name, be it exact or
partial.
arr=( ${(M)arr:#(#i)*/$1/} )
... that works if the name matches exactly but:
arr=( ${(M)arr:#(#i)*/*$1*/} )
... that ends up too broad, $1 matches anywhere irrespective of
slashes.
arr=( ${(M)arr:#(#i)*/*$1[^/]*/} )
... ends up too narrow, it catches a completed name but misses the
exact match which puzzles me because I'd read that: '... anything
except a slash, any number of characters or none' -- which should
find the exact match: ' [^/]* ' should simply be empty, no?