スポンサーリンク

printfスタイルの%03dみたいな形式の番号付きファイル名のパターンをregexに変換して番号を取り出す

sscanf版

%03dみたいなファイル名からIDを取り出したい。sscanfを使う場合、「%03d」だと、「0005」など、3桁でない番号を拾えないので、いっそ%dのほうがいい。

#include <iostream>

int main()
{

  std::string pattern = "myfile_%d.txt";

  std::string fname = "myfile_002010.txt";

  int id;
  sscanf(fname.c_str(), pattern.c_str(), &id);

  printf("%d\n", id);

}

Regex版

#include <iostream>
#include <regex>

int main()
{

  std::string pattern = "myfile_(\\d+)\\.txt";

  std::regex reg_fname(pattern);

  std::string fname = "myfile_0001.txt";
  std::smatch match;
  if (std::regex_search(fname, match, reg_fname)) {
    if (match.size() >= 2) {
      int id = std::stoi(match[1].str().c_str());
    }
  }
}

printf型のパターンを正規表現のパターンに変換して処理

使う側としては正規表現を知らないと分かりづらいので%dを含んだ文字列を正規表現に変換することを考える。

.や+などの記号をエスケープした後で、%dを\d+に置換する。

#include <iostream>
#include <regex>

// 正規表現の特殊文字をエスケープする関数
std::string escapeRegexSpecialCharacters(const std::string& str) {

  // 正規表現の特殊文字を定義
  std::regex special_chars(R"([.^$*+?{}[\]()|\\])");
  // 各特殊文字をエスケープシーケンスに置き換える
  return std::regex_replace(str, special_chars, R"(\$&)");
}

// パターンを正規表現に変換する関数
std::string convertPatternToRegex(const std::string& pattern) {
  std::string regex_pattern;

  // この処理により、
  // "my+file_%d.txt" → "my\+file_%d\.txt"
  // のように、特殊文字をエスケープした文字列になる
  regex_pattern = escapeRegexSpecialCharacters(pattern);

  // %d または %0xd (例: %05d) を正規表現パターンに置換
  // この処理により、
  // "my\+file_%d\.txt"  → "my\+file_(\d+)\.txt"
  std::regex d_pattern(R"(%\d*d)");
  regex_pattern = std::regex_replace(regex_pattern, d_pattern, R"((\d+))");
  return regex_pattern;
}
int main()
{
  // ファイル名のパターン
  std::string pattern = "my+file_%d.txt";

  // ファイル名のパターンを正規表現に変換
  std::string reg_pattern = convertPatternToRegex(pattern);

  std::regex regexpattern = std::regex(reg_pattern);


  // このファイル名から番号を取り出す
  std::string fname = "my+file_002010.txt";

  std::smatch match;
  if (std::regex_search(fname, match, regexpattern)) {
    if (match.size() >= 2) {
      int id = std::stoi(match[1].str().c_str());
      std::cout << id << std::endl;
    }
  }
}

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

日本語が含まれない投稿は無視されますのでご注意ください。(スパム対策)


この記事のトラックバックURL: