c++ - 如何使用正则表达式 C++ 将文本文件解析为变量?

标签 c++ arrays regex parsing text

请帮助我实现将此序列转化为有意义的输出的梦想。 :)

查看正则表达式,它有效!:http://regex101.com/r/iM4yN2/1 现在我只需要知道如何使用它。如果我可以将其放入多维数组中,例如configFile[0][0] = [Tuner,] 可以。或者如果我能把它变成一个逗号分隔的列表,我就可以再次解析它并将它放入数组,最后输出到单个变量。无论如何,您不需要详细说明如何实际分配变量,如果我真的需要帮助,我会提出另一个问题。主要是我需要有关使用正则表达式函数和将数据输出到 SOME 变量的帮助,我可以在其中访问每行 = 符号两侧的各种文本。

正则表达式:

^[\t ]*(.*?)\s*=[\t ]*(.*?)(#.*)?$

测试字符串:

    ### MODULES ###
Tuner         =  
 PitchDetector = 0
PhaseLocker   = 0
FileOutput    = 1

### FILE MANAGER ###
RenameFile_AvgFreq  =  dfgsdfg dsf gdfs g #gdrgk
RenameFile_NoteName = 0
    RenameFile_Prefix   = "The String Is Good"
RenameFile_Suffix   = ""
OutputFolder        = "..\Folder\String\"

### PITCH DETECTOR ###
AnalysisChannel = 1  #int starting from 1
BlockSize             = 8  #power of 2
Overlap               = 16 #power of 2
NormalizeForDetection = 0

### TUNER ###
Smoothing = 0.68
Envelope  = 0.45

### PHASELOCKER ###
FFTSize    = 1024 #powert of 2
FFTOverlap = 54687
WindowType = 0
MaxFreq    = 5000

我的变量:

//Modules
bool Tuner;
bool PitchDetector;
bool PhaseLocker;
bool FileOutput;

//File Manager
bool RenameFile_AvgFreq;
bool RenameFile_NoteName;
std::string RenameFile_Prefix;
std::string RenameFile_Suffix;
std::string OutputFolder;

//Pitch Detector
int AnalysisChannel;
int BlockSize;
int Overlap;
bool NormalizeForDetection;

//Tuner
float Smoothing;
float Envelope;

//Phaselocker
int FFTSize;
int FFTOverlap;
int FFTWindowType;
float FFTMaxFreq;

最后的说明:我花了很长时间研究 C++ 正则表达式函数……非常令人困惑的东西。我知道如何在 python 中不假思索地做到这一点。

最佳答案

包括以下内容:

#include <string>
#include <regex>

声明一个字符串和正则表达式类型:

std::string s;
std::regex e;

在您的主函数中,分配字符串和正则表达式变量并调用正则表达式函数(您也可以在声明它们时分配变量):

int main()
{
    s="i will only 349 output 853 the numbers 666"
    e="(\\d+)"
    s = std::regex_replace(s, e, "$1\n", std::regex_constants::format_no_copy);

    return 0;
}

请注意我是如何将结果直接放回到字符串中的。当然,您可以使用不同的字符串来存储结果。 “std::regex_constants::format_no_copy”是一个标志,告诉正则表达式函数只输出“子字符串”,也就是组匹配。还要注意我是如何在“\d+”上使用双斜杠的。如果您的正则表达式模式不起作用,请尝试使用双斜线。

使用正则表达式查找键/值对,例如“BlockSize = 1024”,您可以创建一个模式,例如:

BlockSize\s*=\s*((?:[\d.]+)|(?:".*"))

在 C++ 中,您可以创建正则表达式模式:

expr = key+"\\s*=\\s*((?:[\\d.]+)|(?:\".*\"))";

并返回匹配结果:

config = std::regex_replace(config, expr, "$1", std::regex_constants::format_no_copy);

并将它们放在一个能够返回默认值的函数中:

std::string Config_GetValue(std::string key, std::string config, std::string defval)
{
    std::regex expr;
    match = key+"\\s*=\\s*((?:[\\d.]+)|(?:\".*\"))";
    config = std::regex_replace(config, expr, "$1", std::regex_constants::format_no_copy);
    return config == "" ? defval : config;
}

完整代码(在需要时使用 std::stoi 和 std::stof 将字符串转换为数字,并使用 auto 类型,因为右侧 (RHS) 清楚地表明了类型是什么):

#include "stdafx.h"
#include <string>
#include <regex>
#include <iostream>

std::string Config_GetValue(std::string key, std::string config, std::string defval)
{
    std::regex expr;
    match = key+"\\s*=\\s*((?:[\\d.]+)|(?:\".*\"))";
    config = std::regex_replace(config, expr, "$1", std::regex_constants::format_no_copy);
    return config == "" ? defval : config;
}


int main()
{
    //test string
    std::string s = "    ### MODULES ###\nTuner         =  \n PitchDetector = 1\n PhaseLocker = 0 \nFileOutput    = 1\n\n### FILE MANAGER ###\nRenameFile_AvgFreq  =  dfgsdfg dsf gdfs g #gdrgk\nRenameFile_NoteName = 0\n    RenameFile_Prefix   = \"The String Is Good\"\nRenameFile_Suffix   = \"\"\nOutputFolder        = \"..\\Folder\\String\\\"\n\n### PITCH DETECTOR ###\nAnalysisChannel = 1  #int starting from 1\nBlockSize             = 1024  #power of 2\nOverlap               = 16 #power of 2\nNormalizeForDetection = 0\n\n### TUNER ###\nSmoothing = 0.68\nEnvelope  = 0.45\n\n### PHASELOCKER ###\nFFTSize    = 1024 #powert of 2\nFFTOverlap = 54687\nWindowType = 0\nMaxFreq    = 5000";

    //Modules   
    auto FileOutput    = stoi(Config_GetValue("FileOutput", s, "0"));
    auto PitchDetector = stoi(Config_GetValue("PitchDetector", s, "0"));
    auto Tuner         = stoi(Config_GetValue("Tuner", s, "0"));
    auto PhaseLocker   = stoi(Config_GetValue("PhaseLocker", s, "0"));

    //File Manager
    auto RenameFile_AvgFreq  = stoi(Config_GetValue("RenameFile_AvgFreq", s, "0"));
    auto RenameFile_NoteName = stoi(Config_GetValue("RenameFile_NoteName", s, "0"));
    auto RenameFile_Prefix   = Config_GetValue("RenameFile_Prefix", s, "");
    auto RenameFile_Suffix   = Config_GetValue("RenameFile_Suffix", s, "");
    auto OutputFolder        = Config_GetValue("FileOutput", s, "");

    //Pitch Detector
    auto AnalysisChannel       = stoi(Config_GetValue("AnalysisChannel", s, "1"));
    auto BlockSize             = stoi(Config_GetValue("BlockSize", s, "4096"));
    auto Overlap               = stoi(Config_GetValue("Overlap", s, "8"));
    auto NormalizeForDetection = stoi(Config_GetValue("NormalizeForDetection", s, "0"));

    //Tuner 
    auto Smoothing     = stof(Config_GetValue("Smoothing", s, ".5"));
    auto Envelope      = stof(Config_GetValue("Envelope", s, ".3"));
    auto TransientTime = stof(Config_GetValue("TransientTime", s, "0"));

    //Phaselocker   
    auto FFTSize       = stoi(Config_GetValue("FFTSize", s, "1"));
    auto FFTOverlap    = stoi(Config_GetValue("FFTOverlap", s, "1"));
    auto FFTWindowType = stoi(Config_GetValue("FFTWindowType", s, "1"));
    auto FFTMaxFreq    = stof(Config_GetValue("FFTMaxFreq", s, "0.0"));

    std::cout << "complete";
    return 0;
}

关于c++ - 如何使用正则表达式 C++ 将文本文件解析为变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26539605/

相关文章:

javascript - 为什么 String() 在 JS 中会压平数组?

ruby - 将 _()_ 中的最后一组与 Ruby 中的正则表达式匹配

c++ - Visual Studio MFC C++ "CFormView"从 "base class"下拉列表中丢失

c++ - 默认的构造函数和析构函数是内联的吗?

c++ - 使用 g++ 中设置的 -O2 执行 std::string 分配时无效 free

java - 正则表达式 : match any file under a certain directory, 除非叶目录被称为 "script"

javascript - 接受数字并在文本字段中清空的指令

c++ - 如何获取小部件窗口句柄以传递给 Qt 中的 win32 api MessageBox

java - 从用户生成的多维数组输出数据

arrays - 如何将命名列表转换为对象数组