【问题标题】:get line from file and use as regular expression(regex)从文件中获取行并用作正则表达式(regex)
【发布时间】:2014-07-10 07:36:49
【问题描述】:

我制作了一个文件(.txt)来放置正则表达式。
每行包含一个正则表达式,我想从文件中读取正则表达式,然后创建一个像 boost::regex exp(line); 这样的正则表达式 line 代表我从文件中获取的正则表达式。
我使用函数regex_search(text, what, exp) 来匹配文本中的 exp。但它不匹配,当我直接使用boost::regex exp("((?<destination_ip>\\S+)?)"); 时,它清楚地匹配。
那么如何从文件中获取行并用作boost::regex exp(line);


我的流到文件的代码是:

using namespace boost;
ifstream rgxFile("regex.txt", ios::in);
smatch what;

while(getline(rgxFile, line))
{    
    regex exp(line);
    if( regex_search(text, what, exp) )
    {
        cout<<"destination IP: "<<what["destination_ip"]<<" ";   
    }
    else
    {
        cout<<"Nothing Found.";
    }
}   

我认为读取文件和获取线路有问题!

更新:

有一个显示访问网站的日志文件。即这是一行日志文件:

  192.168.1.9

(它包含其他东西,但这已经足够了)。

我想获取 IP 并使用它们。那个正则表达式很好,但是有些行包含不匹配的内容。

所以我需要一个包含许多正则表达式的文本文件。如果其中一个文本行不匹配,请使用另一个正则表达式来匹配它。

所有正则表达式匹配所有文本文件(log.txt)。但是当我将正则表达式放入文件并读取它们时,它不匹配任何东西。

这正是 regex.txt 中的正则表达式:

((?<destination_ip>\\S+)?)(\\s[+-]){2} \\[(?<timestamp>\\d{2}\/\\w{3}\/\\d{4}:\\d{2}:\\d{2}:\\d{2})\\s+[+-]\\d{4}\\] \"(?<referer_uri>.*)\"<br/>

这是一行访问文件(log.txt):

192.168.1.9 - - [20/Apr/2014:07:46:19 -0400] "GET /dvwa/favicon.ico HTTP/1.1" 200 1406 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0"

【问题讨论】:

  • 与文本字符串不匹配
  • 那么,第一步是确定您的字符串实际上是正确的......
  • 是的,直接使用时,匹配正确
  • 您可以打印行并检查是否正确
  • 你为什么用 C++ 做这个?您是否考虑过使用单个正则表达式((?&lt;destination_ip&gt;('\\d+\\.){3}\\d+|bogus) 来匹配 IP 以及“伪造”)?我闻到a XY-problem

标签: c++ regex file boost iostream


【解决方案1】:

确保文件包含

((?<destination_ip>\S+)?)

而不是,例如

"((?<destination_ip>\\S+)?)"

您/可能/还将std::ios::binary 标志添加到 istream。

编辑使用来自 OP 的额外信息,这里有一个简单的证明:Live On Coliru

#include <iostream>
#include <fstream>
#include <boost/regex.hpp>

int main()
{
    using namespace boost;
    std::ifstream rgxFile("regex.txt", ios::in);
    std::ifstream input("input.txt");

    std::string line, text;
    while (getline(input, text))
    {
        while(getline(rgxFile, line))
        {    
            smatch what;
            regex exp(line);
            if (regex_search(text, what, exp))
            {
                std::cout << "destination IP: " << what["destination_ip"] << " ";
            } else
            {
                std::cout<<"Nothing Found.\n";
            }
        }   
    }   
}

打印

destination IP: 192.168.1.9

当 input.txt 为:

192.168.1.9 - - [20/Apr/2014:07:46:19 -0400] "GET /dvwa/favicon.ico HTTP/1.1" 200 1406 "-" "Mozilla/5.0 (Windows NT 6.3; WOW64; rv:28.0) Gecko/20100101 Firefox/28.0"

还有 regex.txt:

((?<destination_ip>\S+)?)(\s[+-]){2} \[(?<timestamp>\d{2}/\w{3}/\d{4}:\d{2}:\d{2}:\d{2})\s+[+-]\d{4}\] "(?<referer_uri>.*)"

CAVEAT 如您所见,indeed you had too many \ escapes(input.txt 不是 C++ 字符串文字)以及您管理 @987654331 的事实@ 最后让我怀疑你应该这样做,更不用说在 C++ 中了。

【讨论】:

  • 不,它不匹配任何东西,而且 ios::binary 也不工作。
  • 这完全绕过了提出的问题。你检查文件内容了吗?也许是时候展示你正在使用什么
  • 在 c++ 中,正则表达式 ((?\S+)?) 必须有双反斜杠,如 \\S+
  • 再次,您回避了问题的实际答案。关键是,在文件中您不需要 需要双反斜杠。 (你不能通过对其他事情说“真实”的话来回答问题
  • 对不起,如果我判断得太早了,但我尝试了很多,它与一个反斜杠不匹配。
猜你喜欢
  • 2020-08-29
  • 1970-01-01
  • 1970-01-01
  • 2012-03-12
  • 1970-01-01
  • 2012-10-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多