Text Fileは行末という区切りが付きます。処理系に依存して CR , LF , CR+LF の3種類が多いです。
1byteに統一していれば、混乱することは無いのですが、歴史的背景で、MS系のみ行末は CR+LFです。
C言語系はで \n は処理系に合わせて、CR か LFに読み替えてくれた気がします。CR+LFの2byteも1byteに読み替えてくれる処理系もあったように思います。(記憶違いかも知れませんが)
その際、MS系だとByte処理でカウントしていると元データと処理結果の累積値が異なってくるので煩雑になったりしました。
正規表現の文末の識別に "$"というコントロールCHARがあります。
これを行末として動作させるオプションに RegexOptions.Multilineがあります。
素直に "lineEnd\s*$" と 指定しても、行末を認識してくれません。行末の認識は lf(0x0A)で判断しているので、 lineEnd<行末> だと lineEnd(0x0D)(0x0A) となっていてパターンがマッチしません。
moto = moto.Replace(vbCr, "") の一文を加えると、適切に処理してくれるのですが、不可避でしょうが不細工感が残ります。
文末や\nは改行という表現をするからには, 文末は 0x0A でなく0x0Dが該当しそうな気もします。これも不可避ですね。
二バイトで改行というのは当時は意味があったようですが、今は足枷になってる感がします。長期に渡って使える規格ってできないものですね。
MS系の処理系なのに文末を 0x0A で処理するのはおかしいような気もします。他の処理系との互換性を重視したのであれば方言が強いし...よく解かりません。