在Python中使用节解析纯文本
我有这样的文本:在Python中使用节解析纯文本,python,parsing,Python,Parsing,我有这样的文本: bla bla bla bla some on wanted text.... **************************************************************************** List of 12 base pairs nt1 nt2 bp name Saenger LW DSSR 1 Q.C0
bla bla bla
bla some on wanted text....
****************************************************************************
List of 12 base pairs
nt1 nt2 bp name Saenger LW DSSR
1 Q.C0 Q.G22 C-G WC 19-XIX cWW cW-W
2 Q.C1 Q.G21 C-G WC 19-XIX cWW cW-W
3 Q.U2 Q.A20 U-A WC 20-XX cWW cW-W
****************************************************************************
another unwanted text ...
another unwanted text
我想做的是提取以xxx碱基对列表开始的部分
并以它遇到的第一个******
结束
在某些情况下,此部分根本不出现。如果发生这种情况
它应该只输出“无”
如何使用Python实现这一点
我试过了,但失败了。它根本不打印输出
import sys
import re
def main():
"""docstring for main"""
infile = "myfile.txt"
if len(sys.argv) > 1:
infile = sys.argv[1]
regex = re.compile(r"""List of (\d+) base pairs$""",re.VERBOSE)
with open(infile, 'r') as tsvfile:
tabreader = csv.reader(tsvfile, delimiter='\t')
for row in tabreader:
if row:
line = row[0]
match = regex.match(line)
if match:
print line
if __name__ == '__main__':
main()
在代码末尾,我希望它能打印出以下内容:
nt1 nt2 bp name Saenger LW DSSR
1 Q.C0 Q.G22 C-G WC 19-XIX cWW cW-W
2 Q.C1 Q.G21 C-G WC 19-XIX cWW cW-W
3 Q.U2 Q.A20 U-A WC 20-XX cWW cW-W
或者干脆
NONE
使用re.findall
尝试此正则表达式。请参阅演示
在代码末尾,我希望它能打印出以下内容:
nt1 nt2 bp name Saenger LW DSSR
1 Q.C0 Q.G22 C-G WC 19-XIX cWW cW-W
2 Q.C1 Q.G21 C-G WC 19-XIX cWW cW-W
3 Q.U2 Q.A20 U-A WC 20-XX cWW cW-W
有两个问题。正则表达式有点过于严格。循环不识别正则表达式匹配作为起点。而且,******
端点没有提前退出
以下是一些可以帮助您开始的工作代码:
import re
text = '''
bla bla bla
bla some on wanted text....
****************************************************************************
List of 12 base pairs
nt1 nt2 bp name Saenger LW DSSR
1 Q.C0 Q.G22 C-G WC 19-XIX cWW cW-W
2 Q.C1 Q.G21 C-G WC 19-XIX cWW cW-W
3 Q.U2 Q.A20 U-A WC 20-XX cWW cW-W
****************************************************************************
another unwanted text ...
another unwanted text
'''
regex = re.compile(r"List of (\d+) base pairs")
started = False
for line in text.splitlines():
if started:
if line.startswith('*******'):
break
print line
elif regex.search(line):
started = True
您可以使用re模块的
MULTILINE
和DOTALL
标志
#!/usr/bin/python
import re
f = open('myfile.txt','r').read()
pat = re.compile("""
List\ of\ \d+\ base\ pairs$ # The start of the match
(.*?) # Note ? to make it nongreedy
^[*]+$ # The ending line
""", re.MULTILINE+re.DOTALL+re.VERBOSE)
mat = pat.search(f)
if mat:
print mat.group(1).strip()
else:
print 'NONE'
注:
- 如果文件中有多行星号,则需要在
之后添加*
,以使其不冻结?
- 由于使用了
,因此需要对初始字符串中的空格进行转义(re.VERBOSE
)。否则,将忽略空白,并且找不到匹配项李>Lists\of\…
f=open(my_file).read()
print ''.join(re.findall('\s+nt1[^\n]+\n|\s+\d+\sQ\.[^\n]+\n',f,re.M))
它接受以nt1或number+Q开头的内容,就像传递给
re.findall
的第一个字符串一样,这个解决方案以什么方式失败?这意味着我们应该将所有文本都拼凑成一个变量test\u str
对吗?@pdubois right!!!`f=open('some.txt','r')test_Str=f.read()'类似这样
f=open(my_file).read()
print ''.join(re.findall('\s+nt1[^\n]+\n|\s+\d+\sQ\.[^\n]+\n',f,re.M))