2016-01-23 36 views
1

我想分割JS空間中的字符串,除非引號中的空格。但是,應該保留不完整的報價。我並不擅長於正則表達式巫術,並使用正則表達式以下已:拆分字符串除空引號之外的空格,但包括不完整的引號

var list = text.match(/[^\s"]+|"([^"]*)"/g) 

但是,如果我提供像sdfj "sdfjjk該輸入將成爲["sdfj","sdfjjk"]而非["sdfj",""sdfjjk"]

+1

也許['var re = /\S+|"([^"]*)"/g;'](https://jsfiddle.net/8bxep40n/1/)? –

+0

你是上帝,謝謝你 – nanogru

+0

我會發帖然後 –

回答

1

您可以使用

var re = /"([^"]*)"|\S+/g; 

通過使用\S(= [^\s]),我們剛剛從否定的字符類降"。 通過在\S+之前放置"([^"]*)"模式,我們確保引號中的子字符串在以前不會被撕掉。如果字符串包含配對良好的引用子字符串,並且最後一個未配對,這應該工作。

演示:

var re = /"([^"]*)"|\S+/g; 
 
var str = 'sdfj "sdfjjk'; 
 
document.body.innerHTML = JSON.stringify(str.match(re));

請注意,以獲得捕獲文本在兩者之間引號,你需要在一個循環中使用RegExp#exec(如String#match 「滴」 子匹配)。

UPDATE

什麼downvoting downvoter思想的時候,但讓我猜不知道。引號通常用於單詞字符。如果有一個「狂野」的引用,它仍然是一個字前後的引用。

所以,我們可以利用單詞的邊界是這樣的:

"\b[^"]*\b"|\S+ 

regex demo

這裏,"\b[^"]*\b"匹配之後是文字字符一個",然後匹配比"其他零個或多個字符,然後接着與前面帶有一個字字符"

在這個方向進一步移動,我們可以讓它儘可能:

\B"\b[^"\n]*\b"\B|\S+ 

隨着\B"我們需要"應以非單詞字符開頭,並且"\B應遵循與非字字符。

another regex demo

在很大程度上取決於你有什麼具體問題與特定的輸入!

+0

中顯示的一個,我在'text ='abc'def ghi「lmn」opq''上試過了。它返回'[「abc」,「」def「,」ghi「」,「lmn」,「」opq「]' – 2016-01-23 14:13:37

+0

@torazaburo:我補充了更多解釋。 [此演示與您的測試字符串](https://regex101.com/r/hQ0lU1/1) –

+0

@nanogru:如果答案碰巧無法使用您的輸入,請告訴我,我描述了它應該工作的時間在回答中 –

0

嘗試以下方法:

text.match(/".*?"|[^\s]+/g).map(s => s.replace(/^"(.*)"$/, "$1")) 

此反覆發現任一適當引用的子串(第一),OR非空白的其它序列。 map部分是刪除引用子字符的引號。

> text = 'abc "def ghi" lmn "opq' 
< ["abc", "def ghi", "lmn", ""opq"] 
-1

可以去除從輸入一個潛在的最後一個孤立的報價後,使用這種分裂:

var text = 'abc "def ghi" lmn "opq'; 
var arr = text.replace(/((?:(?:[^"]*"){2})*[^"]*)(?:"|$)/g, '$1'). 
       split(/(?=(?:(?:[^"]*"){2})*[^"]*$)\s+/g); 

//=> [abc, "def ghi", lmn, opq] 

text = 'sdfj "sdfjjk'; 
var arr = text.replace(/((?:(?:[^"]*"){2})*[^"]*)(?:"|$)/g, '$1'). 
       split(/(?=(?:(?:[^"]*"){2})*[^"]*$)\s+/g); 

//=> [sdfj, sdfjjk] 

這裏先replace檢測並text刪除最後一個孤立的報價,然後我們就後跟甚至空格使用split引號的數量(從而確保空格在引號之外)。

+0

請問我能否知道downvote的原因? – anubhava

相關問題