2011-04-27 226 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; 
} 
相關問題