Although I'm not 100% sure what you're asking, I think this will do what you want:
preg_replace(
'/
\'\h*\.\h* # Match a quote and a dot
(\$(?!(?:help)?txt\b) # Avoid matching $txt or $helptxt...
\w+)(?:(\[)([\'"])(\w+)\3(\]))? # ...but do match $var or $arr["idx"]
\h*\.\h*\' # Match a quote and a dot
/x',
'{$1$2$4$5}',
$string)
The comments help, but the regex still looks like Cthulhu swearing, so let's break it down into pieces. The regex is surrounded by the delimiters /, which are just there because preg_replace requires them. The /x at the end allows us to embed spaces and comments into the regex, which we use to make it more comprehensible. The \'\h*\.\h* incantation, which appears at the beginning and the end, matches ' . and the like. (If you want to match single or double quotes, replace the \' with [\'"].) The ' only needs to be escaped with \ because we're in a single-quoted string. The \h indicates any horizontal whitespace (pretty much a space or a tab), with the * allowing any number. Then the \. is a literal ., and the \h* matches more space.
On the second line, we start to match a variable, which we put in capturing group 1 with parentheses. We first match \$, a literal dollar sign, and then we use (?!(?:help)?txt\b). The interior is simple: (?:help)? optionally matches help (the ?: prevent it from being assigned to a capturing group), and then we match txt, and then there's \b which forces a word break (so that $txta is still matched). The (?!...) is a negative lookahead: it doesn't consume any input, but only matches if its interior doesn't. Thus, we only match here if the variable name isn't txt or helptxt.
On the third line, we finish matching the variable. The \w+ just matches one or more "word characters": alphanumerics and the underscore. After this, we save the variable name into capturing group 1—without the array index, if there is one! We then match something in (?:...)?, which just optionally matches it without saving it to a capturing group. The interior matches the ['array_access'] bit, if it exists. We save lots of capturing groups here so that we can delete the quotes like you want. First, we matches a literal [ with \[, and store this in capturing group 2. Then, we match either a single or a double quote with [\'"], and store this in capturing group 3. We then match another string of word characters, which is the array index, and store it in capturing group 4. We then match whichever quote we started with by matching \3, which is capturing group 3. Finally, we match a closing brace and store it in capturing group five. Finally, we match the dot and quote again. (If you don't want to match $arr["idx"] but just $arr['idx'], then change each of ([\'"]) and \3 to \', and change the replacement string to {$1$2$3$4}.)
We then replace this with '{$1$2$4$5}'. If you recall, $1 is the variable name (and the dollar sign), $2 is the [, $4 is the array index (without quotes), and $5 is the ]. Either all of $2, $4, and $5 are defined or none are, so this only produces square brackets when we want them.
Running this on a string will match and replace every occurrence of the regex, which should, I think, do exactly what you want.