The issue you're describing occurs when the source of the attachment doesn't have a corresponding mirror object.
Classic case is the skin. I'll explain the case where it works first. If for example the l_femur_bone was the source of the attachment, and the skin was the target that would work as expected. After doing your string replace, the build() function goes to the r_femur_bone, and builds the attachment with the r_femur_bone as the source, with the same weight map. (remember weights are based on vertex ID) When the attachment is created, Ziva looks up the closest point on the target which in this case is the skin, so no worries.
In the reverse case though (skin is source), there's no corresponding "r_skin", so the attachment is just built on the same vertices. There is a corresponding mirrored target though -- r_femur_bone. The closest point is looked up on that target. That's why you see the attachment stretch over like that.
You need the mirror flag when the skin is the source. This will internally flip the geo in the x axis.
You also need the interp_maps flag to force the interpolation to get the right weights on the source. So, select the skin and run something like this:
import zBuilder.builders.ziva as zva
zObj = zva.Ziva()
zObj.string_replace( '^r_', 'l_' )
zObj.string_replace( '_r_', '_l_' )
zObj.build( mirror=True, interp_maps=True )
Sorry for the long explanation but there it is!