2015-07-10 42 views
1

我有一個像正則表達式來捕捉連續字

"Sony Xperia Z1 Compact" 
"Samsung Galaxy Trend Plus" 
"Samsung Galaxy Tab 2" 

移動設備的名單,我需要一個正則表達式來創建這些字符串標籤以這種方式符合連續字(預期結果):

["Sony", "Sony Xperia", "Sony Xperia Z1", "Sony Xperia Z1 Compact"] 

我曾嘗試一些與積極前瞻:

/(?=([a-z]+\s+[a-z]+))[a-z]+/i 

我獲得:

model = "Samsung Galaxy Trend Plus" 
"Samsung Galaxy Trend Plus" 
model.match(/(?=([a-z]+\s+[a-z]+))[a-z]+/i) 
["Samsung", "Samsung Galaxy"] 

但這個時候你有一個字也不行,所以,添加一個可選的組後:

/(?=([a-z]+\s+[a-z]+))|[a-z]+/i 

我獲得:

model = "Samsung" 
"Samsung" 
model.match(/(?=([a-z]+\s+[a-z]+))|[a-z]+/i) 
["Samsung", undefined] 

所以,試圖概括:

/(?=([a-z]+\s+[a-z]+))(?=([a-z]+\s+[a-z]+\s+[a-z]+))(?=([a-z]+\s+[a-z]+\s+[a-z]+\s+[a-z]+))[a-z]+/i 

我得到

"Samsung Galaxy Trend Plus" 
model.match(/(?=([a-z]+\s+[a-z]+))(?=([a-z]+\s+[a-z]+\s+[a-z]+))(?=([a-z]+\s+[a-z]+\s+[a-z]+\s+[a-z]+))[a-z]+/i) 

["Samsung", "Samsung Galaxy", "Samsung Galaxy Trend", "Samsung Galaxy Trend Plus"] 

而且應該有高達ñ的話,如何讓這個普通的正則表達式(在ñ字變量自由度)? 另外,如何擺脫undefined?正如here所解釋的那樣,我應該使用一個非捕獲組,因此這會阻止我以我正在做的方式捕獲連續的單詞。

+1

的解決方案也成爲一個reg EXP? – epascarello

+0

是的,它必須是一個正則表達式。 – loretoparisi

+7

我不認爲'Sony Xperia Compact'是由連續的單詞形成的。 [這個解決方案怎麼樣](http://jsfiddle.net/e6w0mp31/)? –

回答

1

我可以建議幾乎純粹的正則表達式解決方案。幾乎因爲我需要以交換字以獲得正確的輸出subphrases:

var re = /(?=\b((?:\S+[ \t]*)+))/g; 
 
var str = 'Sony Xperia Z1 Compact'; 
 
    
 
str = str.split(' ').reverse().join(' '); 
 
while ((m = re.exec(str)) !== null) { 
 
    if (m.index === re.lastIndex) { 
 
     re.lastIndex++; 
 
    } 
 
    document.getElementById("t").innerHTML += m[1].split(' ').reverse().join(' ') + "<br/>"; 
 
}
<div id="t"/>

(?=\b((?:\S+[ \t]*)+))正則表達式是捕獲,然後可選空白的非空白字符的所有數據塊(但不換行符號),並確保我們只使用字邊界\b獲得整個單詞。

我認爲很難得到它沒有反轉,因爲我們在JS中沒有可變寬度lookbehind。

+0

這很有道理。這是迄今爲止通過純正則表達式的最佳解決方案! – loretoparisi

0

雖然這不會幫助OP,因爲他們在評論中表示,它必須是一個正則表達式解決方案,但用javascript實現這一點的快速方法是將字符串分割爲空格字符,然後重新構建另一個數組循環:

var s = 'Sony Xperia Z1 Compact'; 

var a = s.split(' '); 
var b = [], c = []; 

for(var i=0; i < a.length; i++) { 
    b.push(a[i]); 
    c.push(b.join(' '));  
} 

c.toString(); = Sony,Sony Xperia,Sony Xperia Z1,Sony Xperia Z1 Compact

看到demo here

+0

這是一個沒有正則表達式的好的解決方案,不幸的是我需要一個正則表達式。無論如何,謝謝你。 – loretoparisi

3

對於那些誰也有類似的問題,但不希望(AB)使用正則表達式:

name = "Samsung Galaxy Trend Plus"; 
 

 
result = name.split(/\s+/g).map(function(_, i, a) { 
 
    return a.slice(0, i + 1).join(" ") 
 
}); 
 

 
document.write(result);

+1

沒有正則表達式並使用函數映射的好解決方案。 – loretoparisi

+0

比我的努力更簡潔,並將我介紹給數組映射函數 – garyh