I find bash regular expressions behave better when enclosed in quotes, even though you have to be a bit careful with this, as direct quoting will cause exact instead of regex matching. To get around this, you can put your regular expression in a variable, quoted, and then reference it in your =~
expression:
#!/bin/bash
arr=(
"def{word} def{word}"
"def{worad} def{worads}"
)
re="def\{([a-z]+)\}.*def\{\1\}"
for i in "${arr[@]}"; do
[[ $i =~ $re ]] || continue
echo ${BASH_REMATCH[1]}
done
Output:
$ ./worad.sh
word
$
This only seems to work in Bash v4, though.