0

如果我有一个输入字符串,如:+key:value+key2:"value+value"+我想要一个返回以下形式的正则表达式我:key:valuekey:"value+value"

理想情况下,我想将它包装在一个返回如下对象的函数中:

{
  key: 'value',
  key2: 'value+value'
}

基本上价值可以是任何东西——任何字符。这里唯一的规则实际上是当值内有一个 + 号时,这不应该分隔正则表达式操作。

4

2 回答 2

3
function parseRagulkasString(str) {
    var regex = /\+([^:]+):((?!")[^+]*|"([^"]*)")/g, o = {}, match;
    while ((match = regex.exec(str)) !== null)
        o[match[1]] = match[match[3] === undefined ? 2 : 3];
    return o;
}

演示:http: //jsfiddle.net/NRhST/2/

解释

  • \+匹配文字加号。
  • ([^:]+)匹配任何非:符号,并被捕获为第一组。
  • :匹配文字冒号。
  • ( ... )捕获第二组:
    • (?!")[^+]*如果后面没有引号,则匹配所有连续的非加号字符。
    • |否则
    • "([^"]*)"匹配引号内的所有非引号字符,并捕获该组 (3)。

while 循环重复运行输入字符串的正则表达式,并按如下方式处理所有匹配项:

  • match[1]是第一个捕获的组,并用作键。
  • 如果值没有被引用,match[3]isundefinedmatch[2]is 值。
  • 否则,match[3]包含引号内的内容,并match[2]包含包含引号的内容。

例如 ( +key:value+key2:"value+value"+):

match[0] = 'key:value'   match[0] = 'key2:"value+value"'
match[1] = 'key'         match[1] = 'key2'
match[2] = 'value'       match[2] = '"value+value"'
match[3] = undefined     match[3] = 'value+value'

因为match[2]只有当值没有被引用时才有意义,所以我们首先检查 if match[3]is undefined。如果是,则不引用该值,我们使用第二组。否则,使用第三组。

注意:此实现需要问题中指定的格式(最后一个加号是可选的)。您可以使用以下方法验证输入字符串是否与预期格式匹配:

function isRagulkasString(str) {
    return /^(\+[^:]+:((?!")[^+]*|"[^"]*"))+\+?$/.test(str);
}
于 2013-04-10T16:05:08.720 回答
1

为此使用正则表达式并不是最简单的解决方案。

这是一个解决方案:

var str = '+key:value+key2:"value+value"+';
var o = {};
str.split('"').map(function(v,i){
  return i%2 ? v.replace(/\+/, 'ù') : v
}).join('').split('+').forEach(function(v){
  var t = v.split(':');
  if (t.length==2) o[t[0]]=t[1].replace(/ù/,'+');
});
console.log(o);

它假设您ù的字符串中没有。如果是这种情况,可能会调整代码以使用另一个(更长的)分隔符。

演示(打开控制台)

请注意,如果您想与 IE8 兼容,则必须使用for循环而不是forEach.

于 2013-04-10T15:07:11.427 回答