我有一个字符串,我想拆分成一个数组。字符串如下所示:
'O:BED,N:KET,OT,N:JAB,FA,O:RPT,'
字符串可以包含任意数量的对象,例如
'O:BED,N:KET,OT,N:JAB,FA,O:RPT,X:BLA,GTO'
我想将此字符串拆分为\w:
的实例,例如O:
所以我最终会得到这样的数组:
['O:BED','N:KET, OT','N:JAB,FA','O:RPT']
我使用以下代码:
var array = st.split(/^(\w:.+)(?=\w:)/g);
但是我最终得到这样的数组:
['','O:BED,N:KET,OT,N:JAB,FA,','O:RPT,']
似乎正则表达式是贪婪的,我该怎么做才能解决它?
注意我正在使用angularjs,最终我想最终得到这个:
var objs = [
{type:O,code: BED, suf: ''},
{type:N, code: KET, suf: OT},
{type:N, code: JAB, suf: FA},
{type:O, code: RPT, suf: ''}
]
答案 0 :(得分:2)
如果您的字符串格式正确将会容易得多。但我们仍然可以通过额外的努力来完成任务。希望以下代码适合您。
var str = 'O:BED,N:KET,OT,N:JAB,FA,O:RPT,X:BLA,GTO';
var a = str.split(',');
var objs = [], obj, item, suf;
for(var i=0; i<a.length;){
item = a[i].split(':');
if(a[i+1] && a[i+1].indexOf(':') == -1){
suf = a[i+1];
i++;
}else{
suf = "";
}
obj = {
type: item[0],
code: item[1],
suf: suf
};
objs.push(obj);
i++;
}
console.log(objs);
答案 1 :(得分:1)
您可以使用RegExp.prototype.exec
方法获取连续匹配,而不是使用分隔符拆分字符串:
var myStr = 'O:BED,N:KET,OT,N:JAB,FA,O:RPT,';
var myRe = /([^,:]+):([^,:]+)(?:,([^,:]+))??(?=,[^,:]+:|,?$)/g;
var m;
var result = [];
while ((m = myRe.exec(myStr)) !== null) {
result.push({type:m[1], code:m[2], suf:((m[3])?m[3]:'')});
}
console.log(result);
答案 2 :(得分:0)
你想做一个string match,然后迭代它。
AngularJS中的完整示例:http://jsfiddle.net/184cyspg/1/
var myString = 'O:BED,N:KET,OT,N:JAB,FA,O:RPT,';
$scope.myArray = [];
var objs = myString.match(/([A-Z])\:([A-Z]*)\,([A-Z]?)/g);
objs.forEach(function (entry) {
var obj = entry.replace(',', ':');
obj = obj.split(':');
$scope.myArray.push({type: obj[0], code: obj[1], suf: obj[2]});
});
答案 3 :(得分:0)
我喜欢正则表达式:)
如果要在所有匹配项中使用全局标记和exec()
,这将匹配字符串的每个对象:
(\w):(\w+)(?:,((?!\w:)\w+))?
唯一真正的诀窍是只将逗号之后的下一位作为后一位处理,如果它看起来不像下一位的类型。
每场比赛都会抓住小组:
如果你只想按照你所说的那样split
,那么你贪婪问题的解决办法是告诉它在逗号上拆分,然后是那些匹配的对象,例如:
,(?=(\w):(\w+)(?:,((?!\w:)\w+))?)
答案 4 :(得分:0)
以下内容并未解决您的正则表达式问题,但是引入underscorejs来处理从简单操作到更复杂操作的替代方法。虽然在这种情况下有点矫枉过正;
// ie. input string = 'O:BED,N:KET,OT,N:JAB,FA,O:RPT,';
.controller('AppCtrl', [function() {
/**
* Split by comma then (chain) eval each (map)
* element that (if-else) contains '0:' is pushed
* into array as a new element, otherwise concat element
*
* :#replace hardcoded values with params
*
* @param String string - a string to split
* @param String prefix - prefix to determine start of new array element ie. '0:'
* @param String delimiter - delimiter to split string ie ','
* @return Array array of elements by prefix
*/
$scope.splitter = function(string) {
var a = [];
var tmp = "";
_.chain(string.split(','))
.map(function(element) {
if(element.indexOf('O:') >= 0) {
element += tmp;
a.push(element);
tmp = "";
} else {
tmp += element;
}
});
return a;
};
}]);
输出:
array: Array[2]
0: "O:BED"
1: "O:RPTN:KETOTN:JABFA"
length: 2
更新:刚刚阅读了对象的要求。 underscorejs允许链接操作。例如,可以调整上面的代码来处理对象,链接到.compact().object().value()以产生输出为Object k:v对;
希望这有帮助。