最終更新日 2025-03-18
JavaScriptの文字列を.NETの文字列に
概要
.NET の Stringでのみ利用可能な.NETメソッド群を利用するには、javascriptの文字列を.NETの文字列に変換する必要があります。
これはなかなか気づきにくい方法となりますので、ここではその手法を紹介します。
javascriptの文字列を.NETの文字列に変換
#JS = loaddll( hidemarudir + @"\hmJS.dll" );
if ( !#JS ) { message "hmJS.dllが読み込めない"; }
#r = dllfuncw( #JS, "DoString",
""""""""""""""""""""""""""""""""""""""""""""""""""
Object.prototype.toClr = function () {
return host.newVar(this.valueOf());
}
function ToDotNetString(jsText) {
return jsText.toClr();
}
var dotNetStr = ToDotNetString("養⽼の滝⼊⼝駐⾞場");
dotNetStr.Normalize(clr.System.Text.NormalizationForm.FormKC);
hm.OutputPane.Output(b);
""""""""""""""""""""""""""""""""""""""""""""""""""
);
freedll( #JS );
このようにすることで、javascriptの文字列を.NETの文字列に変換し、.Normalizeメソッドを利用することが出来るようになりました。
サロゲートペアなどまでも考慮した、文字列の捜査
#JS = loaddll( hidemarudir + @"\hmJS.dll" );
if ( !#JS ) { message "hmJS.dllが読み込めない"; }
#r = dllfuncw( #JS, "DoString",
""""""""""""""""""""""""""""""""""""""""""""""""""
Object.prototype.toClr = function () {
return host.newVar(this.valueOf());
}
function toNETString(jsText) {
return jsText.toClr();
}
function getTargetString() {
return gettotaltext();
}
var walker = clr.System.Globalization.StringInfo.GetTextElementEnumerator(toNETString("養ぎ⽼の滝⼊⼝駐⾞場"));
while (walker.MoveNext())
{
var jsText = walker.GetTextElement();
var dnText = toNETString(jsText);
var normalizedText = dnText.Normalize(clr.System.Text.NormalizationForm.FormKC);
hm.OutputPane.Output(normalizedText);
}
""""""""""""""""""""""""""""""""""""""""""""""""""
);
freedll( #JS );
サロゲートペアなどまでも考慮した、文字列の捜査も可能です。
応用例。サロゲートペアや異体文字などをできるだけ、よく利用される範囲の文字にする
#JS = loaddll( hidemarudir + @"\hmJS.dll" );
if ( !#JS ) { message "hmJS.dllが読み込めない"; }
#r = dllfuncw( #JS, "DoString",
""""""""""""""""""""""""""""""""""""""""""""""""""
Object.prototype.toClr = function () {
return host.newVar(this.valueOf());
}
function main() {
var srcText = gettotaltext();
var srcTextArray = srcText.split("\n");
for(var ix=0; ix < srcTextArray.length; ix++) {
srcTextArray[ix] = normalizeLine(srcTextArray[ix]);
}
var dstText = srcTextArray.join("\n");
if (srcText != dstText) {
settotaltext(dstText);
}
}
function normalizeLine(text) {
// 行全体がSJISの範疇に収まるなら、そのまま採用
if (canConvertSJIS(text)) {
return text;
}
// JavaScriptの文字列を.NETの文字列に変換し、
var netSrcText = text.toClr();
// 合成文字やサロゲートペアも考慮した、ウォーカー(捜査オブジェクト)を構築
var walker = clr.System.Globalization.StringInfo.GetTextElementEnumerator(netSrcText);
// 変換結果
var dstText = "";
// 次の文字が存在する限りにおいて、次の文字へと移動
while (walker.MoveNext())
{
// 文字を取得。「複数の文字」で「1つの文字を形成」している場合、その複数を全部まとめて取得
var jsText = walker.GetTextElement();
// 特殊な正規化をしつつ、変換結果に追加していく
dstText += customNormalize(jsText);
}
return dstText;
}
// 1文字ずつに対して処理する特殊な正規化
function customNormalize(jsText) {
// SJISに収まるならそのまま採用
if (canConvertSJIS(jsText)) {
return jsText;
}
// NFCで正規化をトライ
var dnText = jsText.toClr();
var normNFC = dnText.Normalize(clr.System.Text.NormalizationForm.FormC);
// なんか文字が変化してるならまぁそのまま採用。多分よく使う文字に変換されたんだろう。
if (jsText != normNFC) {
return normNFC;
}
// 仕方がないので、NFKCで変換
var normNFKC = dnText.Normalize(clr.System.Text.NormalizationForm.FormKC);
return normNFKC;
}
// SJISに変換して、元へともどした時、同じ文字なら、SJISに収まる文字
function canConvertSJIS(text) {
try {
if (!this.encoder) {
this.encoder = clr.System.Text.Encoding.GetEncoding("Shift_JIS");
}
var encodedBytes = this.encoder.GetBytes(text);
var decodedText = this.encoder.GetString(encodedBytes);
return text == decodedText;
} catch(e) {}
return false;
}
main();
""""""""""""""""""""""""""""""""""""""""""""""""""
);
freedll( #JS );
このように.NETの文字列とjavascriptを経由して、秀丸エディタの編集文字をうまく編集することが可能です。