2011-04-27 179 views
7

我想在C++中取一个字符串,并找到所有内部包含的IP地址,并将它们放入一个新的矢量字符串。C++正则表达式与提升正则表达式

我读过很多正则表达式的文档,但我似乎无法理解如何做这个简单的功能。

我相信我可以用这个Perl表达式找到任何IP地址:

re("\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b"); 

但我还是难倒如何做休息。

+0

您是否尝试过Boost Regex教程和文档?有一些代码到目前为止与我们分享? – 2011-04-27 12:59:22

+0

你究竟想要与那个正则表达式匹配?首先尝试匹配一个IP地址 – snoofkin 2011-04-27 12:59:43

+1

查看John D Cook的优秀教程[C++ TR1正则表达式入门](http://www.johndcook.com/cpp_regex.html)。它专为那些已经了解RegEx但无法弄清楚如何在C++中完成任务的人设计。 – 2012-05-29 16:49:52

回答

12

也许你正在寻找这样的东西。它使用regex_iterator来获得当前模式的所有匹配。见reference

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

int main() 
{ 
    std::string text(" 192.168.0.1 abc 10.0.0.255 10.5.1 1.2.3.4a 5.4.3.2 "); 
    const char* pattern = 
     "\\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" 
     "\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" 
     "\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)" 
     "\\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\b"; 
    boost::regex ip_regex(pattern); 

    boost::sregex_iterator it(text.begin(), text.end(), ip_regex); 
    boost::sregex_iterator end; 
    for (; it != end; ++it) { 
     std::cout << it->str() << "\n"; 
     // v.push_back(it->str()); or something similar  
    } 
} 

输出:

192.168.0.1 
10.0.0.255 
5.4.3.2 

旁注:你可能是指\\b代替\b;我怀疑你看到匹配退格角色。

+0

迭代器“结束”未初始化。这可以吗? – truthseeker 2013-02-26 12:26:26

+0

@truthseeker:它是由默认构造函数初始化的。 – Vitus 2013-02-26 12:30:48

+1

结尾是默认构造的,但是这个算法有bug(邻接,左对齐,右对齐)和正则表达式是错误的(否则慢)。 – FauChristian 2017-03-21 06:34:24

-1

提供的解决方案非常好,谢谢。虽然我在模式本身发现了一个小错误。

例如,像49.000.00.01这样的东西将被视为有效的IPv4地址,根据我的理解,它不应该(在某些转储处理过程中发生在我身上)。

我建议提高到图案:

"\\b(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)" 
"\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)" 
"\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)" 
"\\.(25[0-5]|2[0-4][0-9]|1[0-9][0-9]|[1-9][0-9]?|0)\\b"; 

这应该只允许0.0.0.0为全零的,我估计是正确的,它会消除所有.00。 .000。等等

0
#include <string> 
#include <list> 
#include <boost/regex.hpp> 
typedef std::string::const_iterator ConstIt; 

int main() 
{ 
    // input text, expected result, & proper address pattern 
    const std::string sInput 
    (
      "192.168.0.1 10.0.0.255 abc 10.5.1.00" 
      " 1.2.3.4a 168.72.0 0.0.0.0 5.4.3.2" 
    ); 
    const std::string asExpected[] = 
    { 
     "192.168.0.1", 
     "10.0.0.255", 
     "0.0.0.0", 
     "5.4.3.2" 
    }; 
    boost::regex regexIPs 
    (
     "(^|[ \t])(" 
     "(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])[.]" 
     "(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])[.]" 
     "(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])[.]" 
     "(2(5[0-5]|[0-4][0-9])|1[0-9][0-9]|[1-9]?[0-9])" 
     ")($|[ \t])" 
    ); 

    // parse, check results, and return error count 
    boost::smatch what; 
    std::list<std::string> ns; 
    ConstIt end = sInput.end(); 
    for (ConstIt begin = sInput.begin(); 
       boost::regex_search(begin, end, what, regexIPs); 
       begin = what[0].second) 
    { 
     ns.push_back(std::string(what[2].first, what[2].second)); 
    } 

    // check results and return number of errors (zero) 
    int iErrors = 0; 
    int i = 0; 
    for (std::string & s : ns) 
     if (s != asExpected[i ++]) 
      ++ iErrors; 
    return iErrors; 
} 
相关问题