0

我有一个带有 ascii 编码的纯 html 文件。我将它加载到 Visual C++ 2012 中的 c++ 子程序中,并尝试从中提取一些模式。但我发现无论正则表达式是什么,都找不到匹配项。

我尝试了使用 cmatch 和 smatch 的程序,但它不适用于从文件加载的字符串。

该文件仅包含 ascii 字符,我需要多行正则表达式支持,但该程序仅适用于分配的字符串,而不适用于从文件加载的字符串。我检查了文件中加载的文本。它已正确加载。问题出在正则表达式上。

void findFrasi(string filename){
    fstream f;
    f.open(filename, fstream::in);
    char* ls;
    ls = (char*)malloc(1000 * 10); 
    f.get(ls, fileSize, char(255));
    std::string s(ls);

    try {
        //s= "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">";
        std::smatch cm;
        std::regex e ("([\\s|\\S]*)(http)([\\s|\\S]*)", std::regex::ECMAScript  | std::regex::icase );

        std::regex_match( s, cm, e, regex_constants::match_any );

        std::cout << "matches:" << cm.size() << std::endl;

        for (std::smatch::iterator it = cm.begin(); it!=cm.end(); ++it) {
            std::cout << *it << std::endl;
        }
    } catch (std::regex_error& e) {
        if (e.code() == std::regex_constants::error_badrepeat)
            std::cerr << "Repeat was not preceded by a valid regular expression.\n";
        else std::cerr << "Some other regex exception happened.\n";
    }

    free(ls);
    f.close();
}

永远不会发生异常!我总是得到输出:matches0

顺便说一句,我还尝试了其他正则表达式脚本,例如 std::regex::ECMAScript,它们并没有什么不同。

4

1 回答 1

1

您可以使用sregex_iterator获取所有匹配项。

像这样的东西(应该在带有 Nov2012CTP 的 Visual C++ 2012 上运行):

#include <regex>
#include <iostream>
#include <fstream>
#include <string>

using namespace std;

int main()
{
    std::string filepath = "jonny_regex_text.txt"; // the file you provided
    std::ifstream ifs(filepath.c_str(), std::ios_base::in | std::ios_base::binary);

    ifs.seekg(0, std::ios_base::end);
    size_t length = static_cast<size_t>(ifs.tellg());
    ifs.seekg(0, std::ios_base::beg);

    std::string text;
    text.resize(length);

    ifs.read(&text[0], length);
    ifs.close();

    std::string pattern(R"((http|https|ftp)\://[a-zA-Z0-9\-\.]+\.[a-zA-Z]{2,3}(:[a-zA-Z0-9]*)?/?([a-zA-Z0-9\-\._\?\,\'/\\\+&amp;%\$#\=~])*)");
    std::regex r(pattern, regex::icase);
    for (std::sregex_iterator it(text.begin(), text.end(), r), end_it; it != end_it; ++it)
    {
        std::cout << it->str() << std::endl;
    }

    return 0;
}

该代码会打印您在文本文件中拥有的所有 URL。

于 2013-03-01T10:28:02.883 回答