【问题标题】:Find and print the number between the parentheses in C++ using Regex使用正则表达式在 C++ 中查找并打印括号之间的数字
【发布时间】:2016-09-13 05:30:47
【问题描述】:

我正在使用此代码来查找 C++ 中括号之间的数字。

我希望从包含这些类型数据的大文件中提取该数字:

SUCCESSFUL CANDIDATES ARE INDICATED WITHIN PARANTHESIS AGAINST THEIR ROLL NUMBER AND THE EXTRA MARKS GIVEN [MAXIMUM FIVE MARKS] TO RAISE THEIR GRADES IN HARDSHIP CASES ARE INDICATED WITH PLUS[+] SIGN AND
GRACE MARKS CASES ARE INDICATED WITH CARET[+] SIGN


600023[545]         600024[554]         600031[605]              600052[560]              ***********

Grade : D
Govt. Degree Boys College, Surjani Town


600060[877]         ***********                   ***********                   ***********                   ***********

///// 在第 2 次迭代中,当找到 [554] 时。 m.size() 不会重置为零,这会导致错误。我该如何解决?我如何从整个文件中全局搜索括号中的数字 [###]

#include <iostream>
#include <fstream>
#include <string>
#include<conio.h>
#include<regex>

using namespace std;

int main () {

 ifstream myfile;

  myfile.open("test.txt") ;


  if(!myfile)

{

cout<<"The file you entered is not present"<<endl;


}


  string str;


  if(myfile.is_open())
   cout<<"file is open";
  else
      cout<<"file is close";

string output;


regex e("\[(\d+)\]");  
smatch m;


  while (!myfile.eof()) {


    myfile >> str;
    cout<<"O="<<str<<endl;

    bool match=regex_search(str,m,e);

    cout<<"m.size() ="<<m.size()<<endl;
    int n=0;
    for( n=0;n<m.size();n++)
    {

        cout<<"m["<<n<<"] :str() =" <<m[n].str()<<endl;

    }



 }

  getch();

  myfile.close();
  return 0;
}

更新: 现在我可以读取数字了。使用字符串。

但我的文件太大,Visual Studio 崩溃了。

我想要一种在文件中全局搜索的方法。

【问题讨论】:

    标签: c++ regex regex-negation regex-lookarounds regex-greedy


    【解决方案1】:

    首先,您应该将regex e("\[(\d+)\]") 修复为regex e("\\[(\\d+)]")(或regex e(R"(\[(\d+)])"),如果您的C++ 环境支持原始字符串文字)。

    然后,您需要获取多个匹配项,而不仅仅是您当前正在执行的所有捕获组内容。使用std::sregex_iterator() 并通过m[1].str() 访问第1 组的内容。

    this C++ demo:

    std::regex r("\\[(\\d+)]");
    std::string s = "SUCCESSFUL CANDIDATES ARE INDICATED WITHIN PARANTHESIS AGAINST THEIR ROLL NUMBER AND THE EXTRA MARKS GIVEN [MAXIMUM FIVE MARKS] TO RAISE THEIR GRADES IN HARDSHIP CASES ARE INDICATED WITH PLUS[+] SIGN AND\nGRACE MARKS CASES ARE INDICATED WITH CARET[+] SIGN\n\n\n600023[545]         600024[554]         600031[605]              600052[560]              ***********\n\nGrade : D\nGovt. Degree Boys College, Surjani Town\n\n\n600060[877]         ***********                   ***********                   ***********                   ***********";
    for(std::sregex_iterator i = std::sregex_iterator(s.begin(), s.end(), r);
                             i != std::sregex_iterator();
                             ++i)
    {
        std::smatch m = *i;
        std::cout << m[1].str() << '\n';
    }
    

    【讨论】:

    • 我正在使用 Visual Studio 2010。当我使用 std::regex r("\[(\\d+)]");当代码执行 this 时,代码崩溃并给出错误。我尝试了许多正则表达式,但大多数都不起作用。
    • 试试r("\\[(\\d+)\\]");
    • 谢谢它的工作。现在我面临的问题是我正在读取的字符串太大以至于 Visual Studio 终止操作。所以我需要一种在文本文件中进行全局搜索的方法。我的数据在文本文件中。我刚刚在我的问题中添加了几行。他们有什么办法吗?而且我仍然不明白为什么 Visual Studio 不支持一些正确的正则表达式。
    • 我正在使用 while (!myfile.eof() ) { getline (myfile,s);} 从文件中获取字符串,然后使用正则表达式迭代器查找数字。
    • 是的,这是处理文本文件最有效的方法:逐行读取并分别处理。我怀疑问题出在正则表达式上。见Fast textfile reading in c++
    【解决方案2】:
    std::string::size_t loc = str.find('[');
    while (loc != std::string::npos) {
        ++loc;
        std::string::size_t end = str.find(']', loc);
        if (end == std::string::npos)
            break;
        std::cout << str.substr(loc, end - loc);
        loc = str.find('[', end);
    }
    

    【讨论】:

    • 可以通过添加一些解释代码在做什么以及它如何解决问题的文本来改进这个仅代码的答案。 -- From Review
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-08-26
    相关资源
    最近更新 更多