2016-01-23 88 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

相关问题