2012-12-03 80 views
4

我有關於如何將可選部分實現爲正則表達式的問題。我已經從解析古老的文本冒險輸入的例子。這突出表明我的任務非常好。這裏是展示我後一個例子:javascript正則表達式中的可選部分(帶捕獲組)

var exp = /^([a-z]+)(?:\s([a-z0-9\s]+)\s(on|with)\s([a-z\s]+))?$/i; 

var strings = [ 
    "look", 
    "take key", 
    "take the key", 
    "put key on table", 
    "put the key on the table", 
    "open the wooden door with the small rusty key" 
]; 

for (var i=0; i < strings.length;i++) { 
    var match = exp.exec(strings[i]); 

    if (match) { 
     var verb = match[1]; 
     var directObject = match[2]; 
     var preposition = match[3]; 
     var indirectObject = match[4]; 

     console.log("String: " + strings[i]); 
     console.log(" Verb: " + verb); 
     console.log(" Direct object: " + directObject); 
     console.log(" Preposition: " + preposition); 
     console.log(" Indirect object: " + indirectObject);  
    } else { 
     console.log("String is not a match: " + strings[i]); 
    } 
    console.log(match); 
} 

我的正則表達式適用於第一個和最後三個字符串。

我知道如何使用其他方法(如.split())得到正確的結果。這是一個嘗試學習正則表達式,所以我不尋找一種替代方法來做到這一點:-)

我已經嘗試添加更多可選的非捕獲組,但我無法得到它的工作:

var exp = /^([a-z]+)(?:\s([a-z0-9\s]+)(?:\s(on|with)\s([a-z\s]+))?)?$/i; 

這適用於三個第一個字符串,但不是最後三個字符串。

所以,我想要的是: 第一個字,直到指定的字某些字符(如「上」),一些字符,直到字符串

棘手的部分的結束是不同的變體。

可以這樣做嗎?

工作溶液:

exp = /^([a-z]+)(?:\s((?:(?!\s(?:on|with)).)*)(?:\s(on|with)\s(.*))?)?$/i; 
+1

'?:'只是生成一個不匹配的組,並且與可選無關。可選組最後有一個'?',或者被量化爲明確可選的,比如'{0,1}'。然而,它不會使用那麼多的可選組,因爲您需要檢查每個匹配組是否存在。 – dognose

+0

我知道?:代表一個非捕獲組。我試圖通過使用以下語法使其成爲可選項: '(?:這部分是可選的)?' – Thomas

+0

我認爲問題在於第一個可選組定義過於貪婪。它匹配字符串的其餘部分,不僅僅是直到單詞「on」或「with」 – Thomas

回答

2

或許有些正則表達式如下:

var exp = /^([a-z]+)(?:(?:(?!\s(?:on|with))(\s[a-z0-9]+))+(?:\s(?:on|with)(\s[a-z0-9]+)+)?)?$/i; 

\s[a-z0-9]+捕獲由一個空間前面的詞。

(?!\s(?:on|with))避免這個詞是「在」或「與」。

因此(?:(?!\s(?:on|with))(\s[a-z0-9]+))+是「on」或「with」之前的單詞列表。你可以測試here

+0

它並沒有給我我想要的東西,但它是朝着正確方向邁出的一步。 「小生鏽鑰匙」的搭配變成了「鑰匙」,「木桌」變成了「桌子」。但正如我所說,這是朝着正確方向邁出的一步。我認爲這一部分是實現這一目標的關鍵。 – Thomas

+0

你想要什麼?也許通過移動第一組詞中的第一個'?:':^([az] +)((?:(?!\ s(?:on | with))(?:\ s [a-z0 ?-9] +))+(:\ S(:關於|帶)(\ S [A-Z0-9] +)+))$'?。 –

+0

我不確定在Stackoverflow上的做法是什麼,但是這個答案引導我朝着正確的方向前進。我的解決方案是'exp = /^([az]+)(?:\s((?:(?!\s(?:on|with)).)*)(?:\s(on|with) \ s(。*))?)?$/i;' – Thomas

相關問題