はじめに
javascript の RegExp を使って CRLF の入った文字列を処理する場合に、^
や$
を使うと処理がおかしくなります。
javascriptのバージョンなど環境によっては異なるかもしれません。
LF
まずは比較のために、LFの文字列の処理結果を書いてみます。
ソース1
result = "1\n2\n".replace(/^/mg, "^");
console.log(result);
出力結果1
^1
^2
^
ソース2
result = "1\n2\n".replace(/$/mg, "$");
console.log(result);
出力結果2
1$
2$
$
ソース1もソース2も正常な動作です。
CRLF
次に改行コードをCRLFにして実行させてみます。
ソース3
result = "1\r\n2\r\n".replace(/^/mg, "^");
console.log(result);
出力結果3
^1^
^2^
^
ソース4
result = "1\r\n2\r\n".replace(/$/mg, "$");
console.log(result);
出力結果4
1$$
2$$
$
余計な場所までマッチしてしまっています。
CR
CRがおかしいのかもしれませんので試してみます。
ソース5
result = "1\r2\r".replace(/^/mg, "^");
console.log(result);
出力結果5
^1
^2
^
ソース6
result = "1\r2\r".replace(/$/mg, "$");
console.log(result);
出力結果6
1$
2$
$
環境によっては改行されないなど差異があるかもしれませんがこのような出力になると思います。
正常ですね、
と書いてしまってましたが、CRを改行コードとして認識するのが問題なのかもしれません。
CRは復帰コードで改行コードではないという記述も見たことありますが、CRの動作を規定する規則はあるのでしょうか?
LFCR
こんな改行コードは無いですが実験してみます 。
ソース7
result = "1\n\r2\n\r".replace(/^/mg, "^");
console.log(result);
実行結果7
^1
^
^2
^
^
ソース8
result = "1\n\r2\n\r".replace(/$/mg, "$");
console.log(result);
実行結果8
1$
$
2$
$
$
異常な出力と言えるのか、正常な出力と言えるのか。
CRを改行コードとして考えれば正しいのでしょうか。
まとめ
以上の事から、CRもLFもそれぞれ1つの改行コードとして扱われていることが分かります。
CRLFの動作も正常と言えるのかもしれません。
現状、CRLFのファイルを使う際は気を付けたほうが良いですね。
CRLFを扱う事の方が珍しいのかもしれませんが。
Windowsを窓から投げ捨てろと、言う事でしょうか(・A・)
余談ですがAtomエディターでWindowsのファイルを扱うと、これが原因で手間が増える事が多いです。
原因に気が付くまで大変でした。
番外
Python3でも試してみました
>>> import re
>>> start = re.compile("^", re.M)
>>> end = re.compile("$", re.M)
>>> start.sub("^", "1\n2\n", 6)
'^1\n^2\n^'
>>> end.sub("$", "1\n2\n", 6)
'1$\n2$\n$'
>>> start.sub("^", "1\r\n2\r\n", 6)
'^1\r\n^2\r\n^'
>>> end.sub("$", "1\r\n2\r\n", 6)
'1\r$\n2\r$\n$'
>>> start.sub("^", "1\r2\r", 6)
'^1\r2\r'
>>> end.sub("$", "1\r2\r", 6)
'1\r2\r$'
>>> start.sub("^", "1\n\r2\n\r", 6)
'^1\n^\r2\n^\r'
>>> end.sub("$", "1\n\r2\n\r", 6)
'1$\n\r2$\n\r$'
CRを改行コードとして扱わないようです。