質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
npm

npmは、Node Packaged Modulesの略。Node.jsのライブラリ・パッケージを管理できるツールです。様々なモジュールを簡単にインストールでき、自分でモジュールを作成し公開する際にも使用できます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

2回答

2553閲覧

特定箇所だけの置換処理を簡潔にしたい

raccy

総合スコア21733

npm

npmは、Node Packaged Modulesの略。Node.jsのライブラリ・パッケージを管理できるツールです。様々なモジュールを簡単にインストールでき、自分でモジュールを作成し公開する際にも使用できます。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

1クリップ

投稿2016/12/29 22:14

概要

JavaScriptで文字列の特定箇所だけ置換するようなことが簡単にできないかと考えています。どのような方法が一番簡潔で、わかりやすく、また、パフォーマンス的にも優れていながら、安全にできるでしょうか?

言ってみればJavaScriptのテンプレート文字列のように使える物です。

JavaScript

1const template = 'http://example.jp/${path}/${code}'; 2const map = new Map([['path', 'hoge'], ['code', 123]]);

とあったとき、

JavaScript

1let evalStr = ''; 2map.forEach((v, k) => evalStr += `const ${k} = "${v}";`); 3evalStr += `\`${template}\``; 4const result = eval(evalStr); 5console.log(result);

とすれば、"http://example.jp/hoge/123"が得られます。こんな感じで変換できるようなもの(パッケージ?、方法?)が欲しいと言うことです。しかし、この方法では、`eval`という**絶対に使いたくない**構文を使用しているため、採用は難しいです。

各種条件

ある程度の妥協は仕方が無いとしても、満たして欲しい条件です。

####テンプレート文字列

  • プログラミングに詳しくない管理者が設定ファイル等で設定することを想定しています。JavaScriptのテンプレート文字列にこだわりはありませんが、書き方のルールが簡単でわかりやすい物でなければなりません。
  • 想定される最終的な文字列は、URI、ファイル・ディレクトリパス(WinおよびMacでの)、ファイル共有パス(URI形式かUNC)で、一行程度です。また、空白及びASCII文字以外も可能でなければなりません。
  • 任意の文字列を設定できるように、エスケープできることは必須です。WinでのパスやUNCは"//サーバ名/パス"や"C:/Windows/System32/"でも認識するようにするため、""を使ってエスケープでもかまいません。

####マップ

  • MapでもObjectでもかまいません。
  • キーは文字列を想定しています。
  • キーは英数字で固定です。ただし、記号"_"は使いたいです。
  • 値はユーザーが入力した任意の文字列を扱います。空白及びASCII文字以外も可能でなければなりません。(".."禁止やURLエスケープ処理等のサニタイジング処理はマップに入れる前に行うため、そこは気にしなくて良いです)

####その他

  • キーについて大文字小文字無視が選択できると嬉しいです。
  • テンプレート自体に間違いがある場合は、エラーやnullを返すなど、わかるようにしてほしいです。
  • npmパッケージ化されていて、@typesパッケージがあればさらに嬉しいです。
  • できればnode-gypによるリビルド無しで動作して欲しいです。

###検討事項

  • evalはセキュリティ上からNGになりました。
  • String.prototype.replaceですと、正規表現の後読みが使えないため、先頭に""を付けるだけのエスケープ処理をどうすれば良いのかわからなくなります。また、キー名が間違っているなどの処理が検知できません。キー一つ一つ順番に適用となるため、単純な実装では、置き変えた後の値を細工することでおかしな動作になる可能性があります。
  • 本格的なテンプレートエンジンの採用も考えましたが、HTMLを想定している場合が多く、機能も多すぎて、管理者が設定を間違ったときのフォローが難しいのでは無いかと考えています。本当に簡易な物で十分なのですが、それだと何が良いのか、調べてもよくわからなかったです。

###動作環境
動作環境は最新のElectronを使用します。Mainプロセス側で動作させる予定です。OSはWinとMac両対応です。
コーディングはTypeScriptで行っています。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

sprintf()の実装には、名前付きの置換フィールドを使えるものがあります。たとえばalexei/sprintf.jsはPythonの%書式化と同じような形式の名前付きフィールドが使えます。

sprintf('http://example.jp/%(path)s/%(code)s', {path: 'hoge', code: 123});

これの場合、テンプレート中の「%」はエスケープして「%%」とする必要があります。

ご質問のいろいろな条件については精査していません。たまたま見つけただけなので他にも類似のものはあると思います。

投稿2016/12/30 02:04

ikedas

総合スコア4229

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2016/12/30 02:13

sprintfに任意のテンプレート文字列を噛ませるのは何か別のトラウマを呼び起こしそうで怖いです。C怖い。sprintfのフォーマット自体は機能が多くて、チェックも難しそうです。ですが、たしかにsprintfは盲点でした。とりあえずmustacheで行くつもりですが、駄目そうだったら、こちらも参考にさせていただきます。
guest

0

ベストアンサー

こんな感じで変換できるようなもの(パッケージ?、方法?)が欲しいと言うことです。

このような変換ができるものはテンプレートエンジンと呼ばれています。つまり、テンプレートエンジンを探されているのですよね? それとも、自分で開発したいということでしょうか?

本格的なテンプレートエンジンの採用も考えましたが、HTMLを想定している場合が多く、機能も多すぎて、管理者が設定を間違ったときのフォローが難しいのでは無いかと考えています。本当に簡易な物で十分なのですが、それだと何が良いのか、調べてもよくわからなかったです。

数あるテンプレートエンジンの中で機能がシンプルだと言われてるものとして、mustacheはいかがですか?

投稿2016/12/29 23:11

mit0223

総合スコア3401

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

raccy

2016/12/30 00:11

mustacheでもまだ機能が多いと思っています。HTMLエスケープとかして貰うと逆に困るというのもありますし…。これ以上、シンプルな物って無いんでしょうか…。それとも、機能制限するなら、テンプレートに{{{x}}}以外の書き方があればエラーにするとかで弾くとかになるんでしょうか…。
mit0223

2016/12/30 01:24

なるほど、機能制限というか、できあがりの文字列も制限したいのですね。やはり要件にあったものを開発するしか無いのではないでしょうか。少しでもサボるのであれば、テンプレートエンジンを呼ぶ前後で正規表現でテンプレートをチェックして制限するとかでしょうか。そうなると、 eval でも同じかと。eval がNGな理由がセキュリティ上の問題だけであれば、 eval をかける前に正規表現でテンプレートをチェックして機能制限した上で eval を呼ぶとか。
raccy

2016/12/30 02:08

テンプレート文字列を読み込む段階で弾く方向でmustacheを使いたいと思います。一から作るでも良いですけど、細かいチェックを自分で考えるよりはできあがりのものを作った方が早くてバグも少なくなりますし。evalはチェック漏れが怖すぎてさすがに無理かなと。色々とアドバイス、ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問