2015-08-13 54 views
2

我想在C++正則表達式,這裏的範圍是一些代碼現在匹配的文本與C++ 11點的正則表達式

#include <iostream> 
#include <regex> 


int main (int argc, char *argv[]) { 
    std::regex pattern("[a-z]+", std::regex_constants::icase); 
    std::regex pattern2("excelsior", std::regex_constants::icase); 
    std::string text = "EXCELSIOR"; 

    if (std::regex_match(text, pattern)) std::cout << "works" << std::endl; 
    else std::cout << "doesn't work" << std::endl; 

    if (std::regex_match(text, pattern2)) std::cout << "works" << std::endl; 
    else std::cout << "doesn't work" << std::endl; 

    return 0; 
} 

,從我的理解,這兩個比賽應該輸出works,但第一個輸出doesn't work,而第二個按預期輸出works。爲什麼?

+0

都應輸出「作品」。我測試了它。 – chathux

+0

它看起來應該可以工作,但在這個在線編譯器上失敗:http://coliru.stacked-crooked.com/a/1fc8753739732402 – Buddy

+0

[Coliru上一套更全面的測試](http://coliru.stacked- crooked.com/a/fd647a5e2cc1f712) – jaggedSpire

回答

2

基於在[re.grammar]中描述的規則,我們有:

- 在匹配re針對字符,二 字符cd序列gular表達的有限狀態機是使用以下規則進行比較:
1.如果(flags() & regex_constants::icase)的兩個字符是相同的,當traits_inst.translate_nocase(c) == traits_inst.translate_nocase(d);
2.否則,如果flags() & regex_constants::collate這兩個字符相等,如果traits_inst.translate(c) == traits_inst.translate(d);
3.否則,如果兩個字符相等,則c == d

這適用於您的pattern2,我們匹配的字符序列,我們有flags() & icase,所以我們做一個比較NOCASE。由於序列中的每個字符都匹配,因此它「起作用」。

但是,與pattern,我們沒有一個字符序列。因此,我們代替使用這樣的規則:

- 在一個正則表達式的有限狀態機的匹配對的字符序列,一個集合元素範圍c1-c2比較 針對一個字符c如下進行:如果flags() & regex_constants::collate是假,則字符被c如果c1 <= c && c <= c2匹配,否則 c按照以下算法匹配:

string_type str1 = string_type(1, 
    flags() & icase ? 
     traits_inst.translate_nocase(c1) : traits_inst.translate(c1); 
string_type str2 = string_type(1, 
    flags() & icase ? 
     traits_inst.translate_nocase(c2) : traits_inst.translate(c2); 
string_type str = string_type(1, 
    flags() & icase ? 
     traits_inst.translate_nocase(c) : traits_inst.translate(c); 
return traits_inst.transform(str1.begin(), str1.end()) 
     <= traits_inst.transform(str.begin(), str.end()) 
    && traits_inst.transform(str.begin(), str.end()) 
     <= traits_inst.transform(str2.begin(), str2.end()); 

由於您沒有設置collate,因此該字符的字面匹配範圍爲a-z。這裏沒有會計icase,這就是爲什麼它「不起作用」。如果您提供collate但是:

std::regex pattern("[a-z]+", 
        std::regex_constants::icase | std::regex_constants::collate); 

然後我們使用描述的算法,它會做一個沒有對比的情況下,結果將是「作品」。這兩種編譯器都是正確的 - 雖然我發現在這種情況下預期的行爲混亂。

+0

但是,'collat​​e'會使模式語言環境變得敏感,這可能會導致不同系統上的不可預知的行爲。我認爲在這種情況下,更好的解決辦法是在兩種情況下宣佈角色。 – nhahtdh

1
std::regex pattern("[a-z]+", std::regex_constants::icase); 

仍然限制小寫字母的模式匹配。我假設字符匹配如在reference中提到似乎不適用於明確指定的字符集,這是我所期望的,並且如果明確指定,處理這些字符集是有意義的。