2015-06-29 84 views
6

我想要一個匹配「香蕉」或「睡衣」但不是「香蕉2」或「香蕉」或「香蕉」或基本上除了那兩個確切兩個單詞之外的任何C++正則表達式。所以我這樣做:與regex.h全字匹配

#include <regex.h> 
#include <stdio.h> 
int main() 
{ 
    regex_t rexp; 

    int rv = regcomp(&rexp, "\\bbananas\\b|\\bpajamas\\b", REG_EXTENDED | REG_NOSUB); 
    if (rv != 0) { 
    printf("Abandon hope, all ye who enter here\n"); 
    } 
    regmatch_t match; 
    int diditmatch = regexec(&rexp, "bananas", 1, &match, 0); 
    printf("%d %d\n", diditmatch, REG_NOMATCH); 
} 

並且它打印1 1就好像沒有匹配一樣。發生了什麼?我也嘗試\bbananas\b|\bpajamas\b爲我的正則表達式,也失敗了。

我問Whole-word matching using regex關於std :: regex,但std :: regex太糟糕了,所以我試圖regex.h。

+5

我不明白爲什麼這會得到downvoted。這是一個小的,很好的,自我包含的編譯問題,只需最少的代碼即可解釋問題。此外,行政首長至少表面上看過文件。 **人們還想要什麼?** –

+0

仇恨者會討厭 –

+0

我也不明白。 *問題*並不差。 – Bathsheba

回答

-1

使用

s == "balances" || s == "pajamas"

,而不是在那裏sstd::string

正則表達式可以簡化一個簡單的解決方案。如果你想要一個固定的比賽,特別避免它們。

+3

「正則表達式可以簡化一個簡單的解決方案。」 - 儘管如此,情況並非如此。例如,OP可能*對香蕉和睡衣沒有真正的興趣,這是一個簡單的例子(說,是的,固定匹配不應該保證一般的正則表達式)。 –

+0

Jamie Zawinski:有些人遇到問題時會想:「我知道,我會用正則表達式。」現在他們有兩個問題。 – Bathsheba

+4

是的,我討厭那個報價jwz。這完全是完全錯誤的,人們引用它作爲教條。 –

0

Konrad留下了一個很好的答案,解決了我的問題,但它以某種方式消失了,所以我不能接受它。下面是印刷正確的事情的代碼,爲後人:

#include <regex.h> 
#include <stdio.h> 

int main() 
{ 
    regex_t rexp; 

    int rv = regcomp(&rexp, "[[:<:]]bananas[[:>:]]|[[:<:]]pajamas[[:>:]]", REG_EXTENDED | REG_NOSUB); 
    if (rv != 0) { 
    printf("Abandon hope, all ye who enter here\n"); 
    } 
    regmatch_t match; 
    int diditmatch = regexec(&rexp, "bananas", 1, &match, 0); 
    printf("%d %d\n", diditmatch, REG_NOMATCH); 
} 
+1

Konrad在評論中指出,這種構造在一個系統上運行,但不在另一個系統上運行,所以它看起來像是圖書館實施。因此,如果它與您的系統一起工作,並且您不需要能夠在其他地方編譯它,那就不是問題。如果你這樣做,你應該尋找一個更好的表達。 – usr2564301

+0

'[[:<:]]不是POSIX標準的一部分。這似乎是一個延伸。 Konrad在刪除他的帖子之前在最後的評論中說過(之後我也轉載了它),但這種語法在Linux上不起作用。 – nhahtdh

+0

GNU有幾個[** extensions **](http://www.gnu.org/software/grep/manual/html_node/The-Backslash-Character-and-Special-Expressions.html#The-Backslash-Character-特殊表達式)'\ <', '\>','\ b'可以在這裏使用 - 但是由於它們是擴展,所以它們只在連接到GNU庫時才起作用,而GNU庫可能不適用於所有系統。 – nhahtdh

1

The POSIX standard指定既不字邊界語法也不看看隱藏和前瞻的語法(這可能被用來模擬一個字的邊界)兩個BRE和ERE 。因此,不可能編寫帶有字邊界的正則表達式,適用於不同的POSIX兼容平臺

對於便攜式解決方案,如果您打算使用C++進行編碼,則應考慮使用PCRE或Boost.Regex。

否則,您將陷入一種非便攜式解決方案。如果你是罰款這樣的限制,有幾個備選方案: