2015-04-04 43 views
0

我有一個奇怪的問題。我正在尋找一個輕量級的正則表達式庫來使用Visual Studio。有人推薦我https://github.com/cesanta/slre;這個庫是我需要的,而且它重量很輕。slre正則表達式庫無法正常工作的開始(?我)不區分大小寫搜索

問題是,它不能在Visual Studio 2013下工作。我用下面的例子編譯它,但printf statament從來沒有達到過。

static const char *str = 
    "<img src=\"HTTPS://FOO.COM/x?b#c=tab1\"/> " 
    " <a href=\"http://cesanta.com\">some link</a>"; 

static const char *regex = "(?i)((https?://)[^\\s/'\"<>]+/?[^\\s'\"<>]*)"; 
struct slre_cap caps[2]; 
int i, j = 0, str_len = strlen(str); 

while (j < str_len && 
     (i = slre_match(regex, str + j, str_len - j, caps, 2, 0)) > 0) { 
    printf("Found URL: [%.*s]\n", caps[0].len, caps[0].ptr); 
    j += i; 
} 

有人可以看看,或者推薦我做錯了什麼。

+1

如何測試它與微不足道的模式第一(「a」匹配「a」)?一個瘋狂的猜測是,你使用的一些正則表達式功能(如(?i)標誌)沒有在slre中實現(或者可能有另一種語法)。 – 2015-04-04 18:19:37

+0

@AntonKovalenko:同意首先測試微不足道的模式。關於可用的功能,似乎支持'(?i)'(寫在文檔中)。 – 2015-04-04 18:36:45

+0

@LucasTrzesniewski:以上代碼是來自slre doc的複製/粘貼示例。 – 2015-04-04 18:38:36

回答

3

似乎有slre庫中的一個錯誤,通過使用(?i)開始您的正則表達式,不區分大小寫匹配。他們有你的例子,即使在他們的單元測試,但不檢查這個測試是否通過:)

好消息是,你可以做一個解決方案不區分大小寫匹配通過刪除(?i)部分在你的正則表達式的開始,並更改在致電slre_matchSLRE_IGNORE_CASE(或簡單地1,因爲這是該常數設置爲slre.h的值)而不是普通0的最後一個參數。

因此的slre_match在你的榜樣的正確用法是

slre_match(regex, str + j, str_len - j, caps, 2, SLRE_IGNORE_CASE) 

並取出(?i)部分在你的正則表達式的開始。

+0

謝謝很多兄弟,但我想我會在這種經歷之後編寫自己的代碼 – opc0de 2015-04-04 19:45:00

+0

@ opc0de:這不一定是從中學到的最好教訓。並非所有的圖書館都是平等的。有些人比其他人有更多的測試。有些人有其他人沒有的錯誤。您是否可以通過自己編寫自己更快速地獲得SLRE所需的功能?這似乎不太可能。但是您需要對您選擇使用的庫進行質量檢查。一個例子失敗並不常見,但它可能發生 - 你證明了這一點。 – 2015-04-04 19:47:37

+0

@ opc0de我認爲最好的方法是消除庫中的這個錯誤併發送一個拉請求:)。這是開源庫的一部分 – halex 2015-04-04 19:50:21

0

正如在另一個答案中提到的(我乍一看可疑),(?i)不被slre支持,儘管它在文檔中提到並在示例中使用。

傳遞SLRE_IGNORE_CASE明確肯定是一種選擇,但你也可以在最簡單的形式添加支持(?i),因爲它的記錄:沒有支持(?iiii)或任何其他標誌,只是固定(?i)前綴。

我的補丁slre.c是相當微不足道的。 (也許將它作爲pull請求提交給github是有意義的)。

diff --git a/slre.c b/slre.c 
index 4a7fd89..d3c7672 100644 
--- a/slre.c 
+++ b/slre.c 
@@ -429,5 +429,9 @@ int slre_match(const char *regexp, const char *s, int s_len, 
    info.caps = caps; 

    DBG(("========================> [%s] [%.*s]\n", regexp, s_len, s)); 
+ if (!strncmp("(?i)",regexp,4)) { 
+ regexp+=4; 
+ info.flags |= SLRE_IGNORE_CASE; 
+ } 
    return foo(regexp, (int) strlen(regexp), s, s_len, &info); 
} 
相關問題