2013-07-10 16 views
-1

我有一个集合(约61000),看起来像将字符串分割为一个对象使用正则表达式

"(((((((((.(((((.&.)))))))))))))) 11,26 : 6,20 (-9.37 = -16.05 + 6.56 + 0.13) GCCAACUGACGUUGUU&AAUAAUUCAGUUGGU"

有很多的各部分之间的空间(1-3)的可变数量的字符串字符串。

最后我要的是这个字符串转换为JavaScript对象:

{ 
    parens: "(((((((((.(((((.&.))))))))))))))", 
    sRNAstart: 11, 
    sRNAend: 26, 
    mRNAstart: 6, 
    mRNAend: 20, 
    netEnergy: -9.37, 
    bindingEnergy: -16.05, 
    sRNAOpenEnergy: 6.56, 
    mRNAOpenEnergy: 0.13, 
    sequences: "GCCAACUGACGUUGUU&AAUAAUUCAGUUGGU" 
} 

这听起来像是正则表达式的人提供工作,胸围可悲的是我不是他。任何人都可以帮助我找出一种方法来实现这一目标吗?

+0

这听起来像一个解析器工作,而不是正则表达式。 –

+3

SO的工作方式是你必须试一试,我们会告诉你如何解决它,你不能只是要求我们这样做。罗伯特哈维是正确的,正规不能解决这个问题很容易没有额外的解析代码。你需要编写你自己的解析器。任何时候你需要做括号/括号匹配,这表明RegEx不是工作的工具 –

+0

我明白这个问题没有捕捉到SO的精神。我只是不知道从哪里开始。感谢@RobertHarvey在下面的回答,我没有意识到'split()'可以做到这一点。 – elsherbini

回答

4

这里是使用正则表达式来解析字符串,用一个内部工作周围那些讨厌的括号的方式:

var s="(((((((((.(((((.&.)))))))))))))) 11,26 : 6,20 (-9.37 = -16.05 + 6.56 + 0.13) GCCAACUGACGUUGUU&AAUAAUUCAGUUGGU"; 

var ob=s.split(/([\s]{1,4}|[,=+:()])/) 
    .filter(/./.test, /\w/) 
    .map(function(chunk, i){ 
     if(i===0) this.parens= s.split(" ")[0]; 
     this[[ "sRNAstart","sRNAend","mRNAstart","mRNAend","netEnergy", 
       "bindingEnergy","sRNAOpenEnergy","mRNAOpenEnergy","sequences" 
     ][i]]= +chunk || (chunk==="0"? 0 : chunk); 
     return this; 
    },{})[0] ; //end ob 


alert(
    JSON.stringify(
    ob, 
    null, 
    "\t" 
) 
); 

结果:

{ 
    "parens": "(((((((((.(((((.&.))))))))))))))", 
    "sRNAstart": 11, 
    "sRNAend": 26, 
    "mRNAstart": 6, 
    "mRNAend": 20, 
    "netEnergy": -9.37, 
    "bindingEnergy": -16.05, 
    "sRNAOpenEnergy": 6.56, 
    "mRNAOpenEnergy": 0.13, 
    "sequences": "GCCAACUGACGUUGUU&AAUAAUUCAGUUGGU" 
} 

编辑:删除使用非通过OLD浏览器捕获更多的x浏览器版本。 编辑:调整:使“0”为0,避免每次设置this.parens,格式化和参数清理。

+0

这很好,谢谢。 – elsherbini

+0

值得注意的是,这需要ECMA5Script 5的['Array.filter'](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter)和['Array .map'](HTTPS://developer.mozilla。org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map)。 – Xotic750

+1

从所描述的任务来看,我猜这不是一个大众市场网站,而是一个在过去5年内在浏览器上运行的个人实用程序应用程序......但是,感谢您提高稳健性并提升体面点。 – dandavis

1

该表达式不能确保括号匹配,但它应该打破模式中的所有内容。

([(.&)]+)\s*(\d+),(\d+)\s*:\s*(\d+),(\d+)\s*\(([-.\d]+)\s*=\s*([-.\d]+)\s*\+\s*([-.\d]+)\s*\+\s*([-.\d]+)\)\s*([GCAU&]+) 
+2

我希望没有人需要弄清楚RegEx实际上在做什么:) –

+0

先生,您是RegEx男士。我觉得如果我可以解释一下这是做什么的,我可以在CS中获得一个单身汉。 – elsherbini

3

A Javascript split() with multiple delimiters应产生一个您需要的所有值的数组。

从那里,它是简单的字符串连接。

+0

正确。但我并不赞成这一点,因为我认为对微不足道的问题提出微不足道的回答违背了SO的精神。 –

+0

Pfft。每个人都是批评家。 –

+0

@WalterTross - 我喜欢它。 。 。可能有相当多的人不知道你可以在'.split()'方法中使用多个demlimiters。 。 。 – talemyn

1

这是一个替代方案,应该也适用于您,并且是跨浏览器。

的Javascript

function parse(string) { 
    if (typeof string !== "string") { 
     throw new TypeError("Attribute must be a string."); 
    } 

    var props = ["parens", "sRNAstart", "sRNAend", "mRNAstart", "mRNAend", "netEnergy", "bindingEnergy", "sRNAOpenEnergy", "mRNAOpenEnergy", "sequences"], 
     array = string.split(/[)]?\s+[(:=+]?\s*|,/), 
     object = {}, 
     value; 

    if (array.length !== props.length) { 
     throw new Error("String could not be converted."); 
    } 

    do { 
     value = array.shift(); 
     object[props.shift()] = +value || value; 
    } while (props.length); 

    return object; 
} 

var ref = "(((((((((.(((((.&.)))))))))))))) 11,26 : 6,20 (-9.37 = -16.05 + 6.56 + 0.13) vGCCAACUGACGUUGUU&AAUAAUUCAGUUGGU"; 

for(var i = 0; i < 3; i += 1) { 
    console.log(ref, parse(ref)); 
    ref = ref.replace(/(\s+)/g, function (all, whitespace) { 
     return whitespace + " "; 
    }); 
} 

jsfiddle

相关问题