Magic mirror madness
Retina, 50 bytes

+`([#.])(([#.])*\|(?&gt;(?&lt;-3&gt;[#.])*))(?!\1)[#.]
#$2#


Try it online! (The first line enables a linefeed-separated test suite.)

I guess this is the opposite of a (no regex) submission.

Explanation

This is simply a regex substitution, which is applied repeatedly (+) until the string stops changing. I'm using balancing groups to make sure that the two mirrored positions are the same distance from the given mirror (backreferences won't do, since the exact string on both sides of the | may be different).

([#.])            # Match and capture a non-mirror cell.
(                 # This will match and capture everything up to its corresponding
                  # cell so that we can write it back in the substitution.
  ([#.])*         #   Match zero or more non-mirror cells and push each one onto
                  #   group 3. This counts the distance from our first match to
                  #   the mirror.
  \|              #   Match the mirror.
  (?&gt;             #   Atomic group to prevent backtracking.
    (?&lt;-3&gt;[#.])*  #     Match non-mirror while popping from group 3.
  )               #   There are three reasons why the previous repetition
                  #   might stop:
                  #   - Group 3 was exhausted. That's good, the next position
                  #     corresponds to the first character we matched.
                  #   - We've reached the end of the string. That's fine,
                  #     the last part of the regex will cause the match to fail.
                  #   - We've hit another mirror. That's also fine, because
                  #     the last part of the regex will still fail.
)
(?!\1)            # Make sure that the next character isn't the same as the first
                  # one. We're looking for .|# or #|., not for #|# or .|.
[#.]              # Match the last non-mirror character.


This is replaced with #$2# which simply replaces both the first and last character of the match with a #.