wregex有什么问题?wregex不支持原生c ++中的[group]功能?

时间:2014-06-03 09:22:49

标签: c++ regex

我想通过wregex获取文件名中的最后一位数字(序列号)。

例如,如果文件名是 LW3_3_1_4_2mm_10X_45kV_LE1_1.0718um_0.35Tran_Export0001.tiff 我将 0001 ;

如果文件名是 LW3_3_1_4_2mm_10X_45kV_LE1_1.0718um_0.35Tran_Export0002.tiff 我会 0002

但我不知道如何在原生c ++中正确使用wregex。

我提到了文件regex_match Function

#include <windows.h>
#include <string>
#include <vector>
#include <stack>
#include <iostream>
#include <map>
#include <regex>

using namespace std;

bool ListFiles(wstring path, wstring mask, map<int,wstring>& files) {
    HANDLE hFind = INVALID_HANDLE_VALUE;
    WIN32_FIND_DATA ffd;
    wstring spec;
    stack<wstring> directories;

    directories.push(path);
    files.clear();



    while (!directories.empty()) {
        path = directories.top();
        spec = path + L"\\" + mask;
        directories.pop();

        hFind = FindFirstFile(spec.c_str(), &ffd);
        if (hFind == INVALID_HANDLE_VALUE)  {
            return false;
        }

        do {
            if (wcscmp(ffd.cFileName, L".") != 0 &&
                wcscmp(ffd.cFileName, L"..") != 0) {
                if (ffd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) {
                    directories.push(path + L"\\" + ffd.cFileName);
                }
                else {

                    wsmatch wideMatch;
                    wregex  fileRegex(L"(^.*\\D)?(?<fileNum>\\d{1,8}).(tiff|tif)$");
                    wstring target(ffd.cFileName);
                    if (regex_match(target.cbegin(), target.cend(), wideMatch, fileRegex))
                    {
                        wcout << wideMatch.str() << endl;
                    }
                    files.insert({ 0, path + L"\\" + ffd.cFileName });
                }
            }
        } while (FindNextFile(hFind, &ffd) != 0);

        if (GetLastError() != ERROR_NO_MORE_FILES) {
            FindClose(hFind);
            return false;
        }

        FindClose(hFind);
        hFind = INVALID_HANDLE_VALUE;
    }

    return true;
} 

int main(int argc, char* argv[])
{
    /*vector<wstring> files;

    if (ListFiles(L"F:", L"*", files)) {
        for (vector<wstring>::iterator it = files.begin();
            it != files.end();
            ++it) {
            wcout << it->c_str() << endl;
        }
    }*/

    map<int, wstring> files;
    if (ListFiles(L"F:", L"*", files))
    {

    }

    getchar();
    return 0;
}

但是有一个错误,我不知道它有什么问题。如下图:regex error picture enter image description here

修改:将wregex fileRegex(L"(^.*\D)?(?<fileNum>\d{1,8}).(tiff|tif)$");更改为wregex fileRegex(L"(^.*\\D)?(?<fileNum>\\d{1,8}).(tiff|tif)$");。实际上我将其写为第二个。

Eidt2:当我将L"(^.*\D)?(?<fileNum>\d{1,8}).(tiff|tif)$"更改为L"(^.*\\D)?\\d{1,8}.tiff$"时,它正常工作。本机c ++中的正则表达式是否不支持组功能 吗

1 个答案:

答案 0 :(得分:1)

您没有使用原始字符串来指定正则表达式,这会在解析转义序列\D\d时导致错误。写下

wregex fileRegex(LR"(^.*\D)?(?<fileNum>\d{1,8}).(tiff|tif)$");

或逃避反斜杠

wregex fileRegex(L"(^.*\\D)?(?<fileNum>\\d{1,8}).(tiff|tif)$");

行字符^的开头应该在第一个捕获组之外:

LR"^(.*\D)?"...

我理解您在\D背后的意图,但只需附加.*就可以使?表达非贪婪。

TR1和C ++ 11正则表达式中的命名捕获组不受支持。您必须从第二个捕获组中删除?<fileNum>

tiff必须转发\.之前要匹配的点。未转义的点将匹配任何角色。

试试这个表达式,它应该和你的一样:

LR"^.*?(\d{1,8})\.tiff?$"