我试图解析大约30,000个文件名的数据。以下是一些例子:
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
我试图提取以下内容:
我刚才使用pyparsing
,所以我很乐意帮忙。
我的第一个猜测是做类似的事情:
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(' -/:_-')
但是当订单关闭或者有额外的单词时(例如tatI
,V3
等),这会失败。
使用Pyparsing - where order of tokens in unpredictable中的建议我尝试使用OneOrMore
运营商:
parser = pyp.OneOrMore(pyp.MatchFirst([pat,
visit,
clone,
primer,
extension]))
parser.setDefaultWhitespaceChars(' -/:_-')
但是在某些情况下错过了primer
:例如A0001-R00-LTR-BA43.ab1
而不是A0001-R00-BA81-tat1.ab1
,原因我不明白。
任何建议都将不胜感激!
答案 0 :(得分:1)
你快到了。你需要匹配额外的令牌(我假设你不关心)。只要确保额外的匹配结束,所以不要吞噬你感兴趣的东西。使用names
作为帖子中定义的列表:
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")
我们可以创建它们的字典以便于访问:
for result in grammar.scanString(names):
print result[0].asDict()
导致
{'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'}