Help us understand the problem. What is going on with this article?

フォルダ名として使用できない文字列を正規表現でいい感じに変換する

More than 1 year has passed since last update.

私はFirefox向けにTab Session Managerという拡張機能を作っています。これは開いているセッションを保存・復元するアドオンで,機能の一つとして保存されたセッションをファイルに書き出してバックアップを保存するオプションがあります。以前は保存場所を特定のフォルダに固定していたのですが,この度保存フォルダを文字列で指定できるオプションを実装することにしました1
フォルダ名をユーザに入力させる上で考えなければいけないことは,フォルダ名には使用できない文字列があるということです。この記事では,フォルダ名として不正な文字列が入力されたときにいい感じに変換する方法を説明します。

前提

ユーザは拡張機能の設定ページからこのようなフォームに入力します。
入力フォーム

ここに入力されたフォルダ名を指定してファイルの保存処理を行うわけですが,例えばfolder?と入力されると保存処理はエラーを吐きます。?はファイル名として使用できないためです。したがって,?-に変換するなどしてエラーを回避する必要があります。

やること

  • 今回は上記の画像の通りフォルダ名のみを対象とする
  • フォルダ名に含まれる特殊文字はハイフンに変換する
    • a:b?c.d"e<f>g|ha-b-c-d-e-f-g-h
    • 今回はフォルダ名が対象なので,ピリオドも特殊文字として扱う
  • ディレクトリの区切り文字として使えるのはスラッシュまたはバックスラッシュとし,出力はバックスラッシュに統一する
    • a/b\ca\b\c
  • 2つ以上連続するスペース,バックスラッシュは1つに変換する
    • a___a\\ba_a\b (スペースを_で表しています)
  • フォルダ名の先頭と末尾のスペースは削除する
    • a_\_b_a\b (スペースを_で表しています)
  • パスの先頭と末尾のバックスラッシュは削除する
    • \a\a
  • OSによって予約された名前(CON,PRNなど)やパスの最大長は今回は考えない

実装

replaceFolderName.js
const replaceFolderName = str => {
  const specialChars = /\:|\?|\.|"|<|>|\|/g;   //使用できない特殊文字
  const slash        = /\//g;                  //単一のスラッシュ
  const spaces       = /\s\s+/g;               //連続したスペース
  const backSlashs   = /\\\\+/g;               //連続したバックスラッシュ
  const sandwich     = /(\s\\|\\\s)+(\s|\\)?/g;//バックスラッシュとスペースが交互に出てくるパターン
  const beginningEnd = /^(\s|\\)+|(\s|\\)+$/g; //先頭と末尾のスペース,バックスラッシュ

  const replacedStr = str
    .replace(specialChars, `-` )               //特殊文字をハイフンに置き換え
    .replace(slash,        `\\`)               //スラッシュをバックスラッシュに置き換え
    .replace(spaces,       ` ` )               //連続するスペースを一つに置き換え
    .replace(backSlashs,   `\\`)               //連続するバックスラッシュを一つに置き換え
    .replace(sandwich,     `\\`)               //" \ \"のような"サンドイッチ"をバックスラッシュ一つに置き換え
                                               //→フォルダ名の先頭と末尾のスペースを削除,スペースのみのフォルダを削除
    .replace(beginningEnd, ``  );              //先頭と末尾のスペース,バックスラッシュを削除

  return replacedStr;
};

サンプルはこちら
こんな感じにすれば不正なフォルダ名のエラーを回避できる……はずです。
見落としている点やもっとエレガントな方法があれば教えて頂けると幸いです。


  1. フォルダをinput type=fileではなく入力文字列で指定するのは,拡張機能から指定できる保存先がFirefoxのダウンロードフォルダ以下に限定されるためです。ダウンロードフォルダ以外を指定できないUIにしたいという意図があります。 

sienori
情報系修士学生.Firefox/Chrome向け拡張機能 Tab Session Manger, Simple Translate など作っています.
http://sienori.hatenablog.com/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした