if (/^Dealt .*\[([^][]+)\]$/) {
push @cards, $1;
}
Parentheses in a regular expression "capture" whatever matches the subexpression inside the parentheses, so you can refer to the first (counting opening parentheses from the beginning of the string) as $1, the second parenthesized subexpression match as $2, etc.
The regex looks a bit complex because the delimiters [ and ] are metacharacters, so they need to be backslashed, and there are a few uses of the actual metacharacters in that expression, too. Suppose the delimiters were < and > instead (these have no special meaning in regular expressions), the expression would be /^Dealt.*<([^><]+)>$/ which is at least a little bit easier to read. In so many words, inside the delimiters, use capturing parentheses, capturing as many as possible of any character except the delimiters (or newline, implicitly).