エスケープシーケンスは二度死ぬ
JavaScriptにおいて、変数を利用して柔軟な正規表現処理を実施したいときは、
var tag = "aieeeee"; str.replace(new RegExp(tag, "g"), convertedText);
さて、ここでLaTeX記法の様な「\section」から始まる文字列を正規表現で置換したいとする。変数tagにはどう代入すれば良いか?
解答
解答としては次の様になる。
var tag = "\\\\section"; str.replace(new RegExp(tag, "g"), convertedText);
解説
変数を使用しない正規表現の感覚で、
str.replace("\\section", convertedText);
の様に変数tagに、
var tag = "\\section"; str.replace(new RegExp(tag, "g"), convertedText);
と代入しては「\section」は正規表現で拾われない。
これは、バックスラッシュは特殊文字であるからエスケープ処理をせねばならないが、この処理が二度行われるからである。まず、tagに代入処理があるときにエスケープ処理があるから、\\sectionが格納される。そして、RegExpのコンストラクタを呼び出したときに再びエスケープ処理がされるので、\\sectionは\sectionになる。バックスラッシュのカルテットで、漸く望み通りの正規表現処理が実現されるわけだ*1。
尚、変数を経由せずにコンストラクタに文字列を渡すときも同様である。
str.replace(new RegExp("\\\\" + tag, "g"), convertedText);