2013-06-21 32 views
2

我想要一個* XXX模式相匹配,如「*測試」,「*愛」「*什麼」(如包括hashtag)甚至比賽用在正則表達式

我基本上是試圖匹配丟失:

"*aaa *eee *rrr *ttt".match(/(\s|^)(\*[a-z0-9]{3,150})(\s|$)/img) 

僅返回奇數邏輯匹配:「* AAA」和「* RRR」

當匹配,我想發動機「標記」整個匹配位數爲「已使用」,因此也從測試到下一個塊除去。所以,什麼可以是「無」數字,因爲開始「^」不存在,並且在第二次比賽之前什麼也沒有。

有沒有人有想法解決它?

+0

我試圖uncapture的\ S | ^或用\ s | $使用 「* AAA * EEE *存款準備金率* ttt「.match(/(?:\ s | ^)(\ * [a-z0-9] {3,150})(?:\ s | $)/ img) – jbdemonte

回答

2

試試這個:

/(?:^|\s)(\*[a-z0-9]{3,150})(?=$|\s)/gim 

See demo here

用法:

var match, regex = /(?:^|\s)(\*[a-z0-9]{3,150})(?=$|\s)/gim 
while (match = regex.exec("*aaa *eee *rrr *ttt *[email protected] hhh*iii *uuu*ooo *www")) { 
    console.log(match[1]); 
} 

輸出(匹配的 「標籤」):

*aaa 
*eee 
*rrr 
*ttt 
*www 
+0

這裏需要注意的一點是,和OP的解決方案一樣,任何'標籤'後加標點符號(例如'。!?:;')都不會被正則表達式捕獲。這就是我在我的答案中將OP的'\ s | $'換成'\ b'的原因。 –

+0

@AndyE使用單詞邊界('\ b'),正則表達式匹配'* xxx @'so ... no。如果OP想要匹配標點符號,他必須明確地做到:'(?:^ | \ s)(\ * [a-z0-9] {3,150})(?= $ | \ s | [。 !?:;])'。 – acdcjunior

+0

對吧,實際上這可能是更好的方法。 –

1

嘗試改變正則表達式爲/(\*[a-z0-9]{3,150})/img

看到它在行動:http://regexr.com?35ae3

編輯:繼@AndyE建議,正則表達式可以寫成/(?:\s+|^)(\*[a-z0-9]{3,150})/imghttp://regexr.com?35aec

+1

我假設」 \ s'匹配是爲了不偶然地匹配'aaa * bbb'。 –

+0

@AndyE:可以,但就是OP是不是對 –

+0

太大問題明確表示: 「* AAA * EEE * RRR @ * TTT」 .match(/(?:\ S + | ^)(\ * [A- Z0-9] {} 3150)/ IMG) 匹配* RRR @ =>雖然它不應該,因爲它包含一種非想要的人:@ – jbdemonte

0

從你的正則表達式中刪除\s 。你抓住了開始和結束的空間,所以當你到達*eee時,沒有開始空間。

(\s|^)(\*[a-z0-9]{3,150})(|$)

例子:

http://regexr.com?35ae0

編輯

您還可以通過後加入{0,},這意味着它會尋找的白色任何長度留在\s空間。

/(\s{0,}|^)(\*[a-z0-9]{3,150})(\s{0,}|$)/gim

實施例:http://regexr.com?35ae9

1

的問題是,該空間得到由以前匹配消耗並因此爲當前匹配不可用。

您可以使用預見 - (?=\s|$)而不是(\s|$)。嘗試:

(\s|^)(\*[a-z0-9]{3,150})(?=\s|$) 

以獲得更多關於先行見this

Test

但是在這種情況下,您可以刪除對以下空間的檢查,因爲[a-z0-9]無法匹配空格。根據這一點,另一個選擇是將其更改爲:(如果這符合您的要求)

(\s|^)(\*[^\s]{3,150}) 

[^\s]意味着沒有空格。

+0

我雖然預見未能在網絡正則表達式,我會更深入,謝謝 – jbdemonte

+0

非常感謝,沒關係! 「* AAA * EEE * RRR * TTT」 .match(?/(:\ S | ^)(\ * [A-Z0-9] {3150})(= \ S | $)/ IMG?) lookahead是正確的解決方案 – jbdemonte

2

match對於這裏的工作並不是真正的工具。每個項目都需要額外的解析或修剪,所以你最好從一開始就使用exec做一個while循環。

var match, 
    tags = [], 
    str = "*aaa *eee *rrr *ttt", 
    reg = /(?:\s|^)(\*[a-z0-9]{3,150})\b/gim; 

while (match = reg.exec(str)) 
    tags.push(match[1]); 

console.log(tags) 
//-> ["*aaa", "*eee", "*rrr", "*ttt"] 

注意,正則表達式,\b指字的邊界,並(?:\s|^)意味着比賽,但不捕獲\s^。後者確保match[1]將永遠是標籤。

+0

你在哪裏測試? 我有一個:語法錯誤:無效的正則表達式:/(:\ s | ^?)(\ *([A-Z0-9] {} 3150)\ B /:未終結組 – jbdemonte

+0

@jbd它的作品,我只是把一個額外的支架錯誤;-)現在試試 –

+0

在你的正則表達式中,'\ b'稍微改變了OP的結果。而不是捕獲一個很長的字符串的前150個字符\ b強制字符串爲150個字符或更少。我並不反對這種用法,而是因爲根據請求者的使用情況,它可能有用,所以我想引起人們對細微之處的關注。 –