首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对顺序未知且可能缺少某些项的字符串进行unknown解析。

对顺序未知且可能缺少某些项的字符串进行unknown解析。
EN

Stack Overflow用户
提问于 2014-03-17 21:18:08
回答 1查看 195关注 0票数 2

我试图从大约30,000个文件名中解析数据。以下是几个例子:

代码语言:javascript
复制
A0038clone11-BA28.ab1
A038clone11-BA31.ab1
A0038clone11-BA32.ab1
A0001-R00-tatI-BA29.ab1
A0001-R00-V3-BA31.ab1
A0001-R00-LTR-BA43.ab1
A0001-R00-BA81-tat1.ab1
A0002_R07-Primer7.ab1
A0016_A0053_R01-Primer5.ab1
A0016:A0053-R02-Primer7.ab1
A0017_A0054_R04-Primer5.ab1
A0017_A0054_R07-Primer5.ab1
A0037_R06_042712-Primer7_R.ab1
A0037_R07-Primer5_R.ab1
A0041-R01-12Feb-BA87-tat2.ab1
A0094-R00-BA88-fall to early.ab1
A0094-R02-BA88-need to repeat.ab1
A0107-R01-WZ5-BA86-tat1.ab1
A0111_R04_P5_GC-Primer5.ab1
A0179-R02LTR-BA83_R-bad seq.ab1

我试着提取以下内容:

  • 病人号码(A0-大约)
  • 访问号(R-s),它经常丢失,我假设是默认的R00
  • 底漆(有底漆或底漆之类的)
  • 克隆号(克隆-什么),经常丢失,我假设是clone01

我刚开始使用pyparsing,所以我希望得到一些帮助。

我的第一个猜测是做这样的事情:

代码语言:javascript
复制
pat = pyp.Combine(pyp.Word('A') + pyp.Word(pyp.nums))
visit = pyp.Combine(pyp.Word('R') + pyp.Word(pyp.nums))
clone = pyp.Combine('clone' + pyp.Word(pyp.nums))

primer = pyp.Combine(pyp.oneOf('Primer BA', caseless=True) + pyp.Word(pyp.nums))
extension = pyp.Combine(pyp.Optional(pyp.CaselessLiteral('_R'))+pyp.CaselessLiteral('.ab1'))

parser = pat + pyp.Optional(visit, default='R00') + pyp.Optional(clone, default='clone01') + primer + extension
parser.setDefaultWhitespaceChars(' -/:_-')

但是,当订单取消或其中有额外的单词(如tatIV3等)时,这就失败了。

使用Pyparsing - where order of tokens in unpredictable的建议,我尝试使用OneOrMore操作符,例如:

代码语言:javascript
复制
parser = pyp.OneOrMore(pyp.MatchFirst([pat, 
                                       visit, 
                                       clone, 
                                       primer,
                                       extension]))
parser.setDefaultWhitespaceChars(' -/:_-')

但在某些情况下,这忽略了primer:比如A0001-R00-LTR-BA43.ab1,而不是A0001-R00-BA81-tat1.ab1,原因我不明白。

如有任何建议,将不胜感激!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-03-18 15:58:24

你差点就到了。您需要匹配额外的令牌(我假设您并不关心)。只需确保额外的比赛是在最后,这样才不会吞食你感兴趣的东西。使用names作为文章中定义的列表:

代码语言:javascript
复制
from pyparsing import *

def marker(key):
    return Combine(CaselessLiteral(key) + Word(nums))

pat    = marker("a")
visit  = marker("r")
clone  = marker("clone")
primer = marker("ba") | marker("primer")
sep    = oneOf("- _").suppress()
other  = Word(alphanums + ":")

file_ext = Literal(".").suppress() + Word(alphanums)
EOL    = LineEnd().suppress()

tokens = [pat("pat"),
          visit("visit"),
          clone("clone"),
          primer("primer"),
          sep,other]
grammar = OneOrMore(MatchFirst(tokens)) + file_ext + EOL

通过给中间结果取一个名称,例如clone("clone"),我们可以创建它们的字典,以便于访问:

代码语言:javascript
复制
for result in grammar.scanString(names):
    print result[0].asDict()

结果是

代码语言:javascript
复制
{'clone': 'clone11', 'primer': 'ba28', 'pat': 'a0038'}
{'clone': 'clone11', 'primer': 'ba31', 'pat': 'a038'}
{'clone': 'clone11', 'primer': 'ba32', 'pat': 'a0038'}
{'pat': 'a0001', 'primer': 'ba29', 'visit': 'r00'}
{'pat': 'a0001', 'primer': 'ba31', 'visit': 'r00'}
{'pat': 'a0001', 'primer': 'ba43', 'visit': 'r00'}
{'pat': 'a0001', 'primer': 'ba81', 'visit': 'r00'}
{'pat': 'a0002', 'primer': 'primer7', 'visit': 'r07'}
{'pat': 'a0053', 'primer': 'primer5', 'visit': 'r01'}
{'pat': 'a0016', 'primer': 'primer7', 'visit': 'r02'}
{'pat': 'a0054', 'primer': 'primer5', 'visit': 'r04'}
{'pat': 'a0054', 'primer': 'primer5', 'visit': 'r07'}
{'pat': 'a0037', 'primer': 'primer7', 'visit': 'r06'}
{'pat': 'a0037', 'primer': 'primer5', 'visit': 'r07'}
{'pat': 'a0041', 'primer': 'ba87', 'visit': 'r01'}
{'pat': 'a0094', 'primer': 'ba88', 'visit': 'r00'}
{'pat': 'a0094', 'primer': 'ba88', 'visit': 'r02'}
{'pat': 'a0107', 'primer': 'ba86', 'visit': 'r01'}
{'pat': 'a0111', 'primer': 'primer5', 'visit': 'r04'}
{'pat': 'a0179', 'primer': 'ba83', 'visit': 'r02'}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22465616

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档