Example7:用户支持的模式匹配行
这行代码主要是为了统计某个单词在文本文件中有多少个,代码如下:
import re, sys
myregex = re.compile(sys.argv[2])
counter = 0
fh = open(sys.argv[1])
for line in fh:
if myregex.search(line):
counter += 1
fh.closer()
print(counter)
代码解释如下:
第一,第2行代码:关于sys.argv[2]的用法,举1个小例子,在C盘的C:Users20161111目录下建立一个.py脚本,命名为test.py,输入下面的代码:
import sys
a = sys.argv[0]
print(a)
保存,快捷键Win+R,打开cmd,输入python
test.py,结果如下所示:
C:Users20161111>python test.py
test.py
由此可见,sys.argv[0]表示的就是test.py这个文件本身,现在将tetst.py代码中的sys.argv[0]更改为sys.argv[1],再次运行,输入python
test.py what,如下所示:
C:Users20161111>python test.py what
what
运行的结果变成了what,再次修改,将sys.argv[1]改为sys.argv[2:],运行,输入python
test.py test0 what1 how3 apple4,如下所示:
C:Users20161111>python test.py test0 what1 how3 apple4
['what1', 'how3', 'apple4']
C:Users20161111>
得到的结果是:'what1', 'how3',
'apple4'。再倒回去想一下,sys.argv[0]表示的是test.py本身,sys.argv[1]表示的是输入的第1个参数,sys.argv[2:]表示的是第2个参数往后,这与切片的表示形式是一样的。
结论就是,sys.argv[
]其实就是一个列表,里边的项为用户输入的参数,关键就是要明白这参数是从程序外部输入的,而非代码本身的什么地方,要想看到它的效果就应该将程序保存了,从外部来运行程序并给出参数(参考资料:Python中
sys.argv[]的用法简明解释)。
第二,第4行代码,fh = open(sys.argv[1])表示的就是打开某个文件。
第三,现在运行一下这个脚本,将脚本保存到C盘的根目录下,命名为count_line.py,同时在同一个目录新建一个文本文件,输入以下文字:
line1
line2
line3
line4
将文件命名为line_test.txt,打开cmd,输入命令python
count_line.py
count_test,line,一共是2个参数(前面的python不算),参数1是脚本名称,即count_line.py,参数2是文本文件,即count_test,参数3是要统计的文字,即line,运行结果如下所示:
C:Users20161111>python count_line.py line_test.txt line
4
可以发现,这个文本文件中有4个line这个单词。但是这个脚本有个缺陷,就是,如果一行中有两个line这个单词,它还是会统计为1个,如下所示,将文本文件更改为这样的:
line1
line2
line3
line4 line5
继续运行上述脚本,结果如下所示:
C:Users20161111>python count_line.py line_test.txt line
4
因此,需要对脚本进行更改,更改后的版本如下所示:
import re, sys
myregex = re.compile(sys.argv[2])
counter = 0
fh = open(sys.argv[1])
for line in fh:
counter += len(myregex.findall(line))
fh.close()
print(counter)
运行结果如下所示:
C:Users20161111>python count_line.py line_test.txt line
5
10.
在Python中,正则表达式的规则非常难记,有没有工具可以用来检测正则表达式的正确与否?
答:有个工具是Kodos,这个工具是用Python写成的,输入正则表达式,它能够在相应的输出框显示出正则表达式的结查,官网是:http://kodos.sourceforge.net/,软件是在WIndows下运行的,打开后界面如下所示:
11.
如何通过正则表达式替换一些字符串?
答:如果要实现这个目的,需要用到re.sub()方法,sub就是substitution的简写,它的用法是sub(rpl,str[,count=0])
具体参数的含义如下所示:
rpl:原始的字符串;
str,需要替换原始字符串的字符串。
[,count=0],可选参数,表示替换的最大次数,默认是0,表示替换所有匹配。
re.sub的使用非常类似于replace方法,参见下面的案例,代码如下所示:
这个案例展示的是:删除GC重复(该行有超过3个GC),代码解释参见注释
import re
regex = re.compile("(?:GC){3,}") # 匹配至少3个GC结边的字符串
seq = "ATGATCGTACTGCGCGCTTCATGTGATGCGCGCGCGCAGACTATAAG"
print("Before:", seq)
print("After:", regex.sub("",seq))
结果如下所示:
C:Users20161111>python test.py
Before: ATGATCGTACTGCGCGCTTCATGTGATGCGCGCGCGCAGACTATAAG
After: ATGATCGTACTTTCATGTGATAGACTATAAG
第二个方法:subn(rpl,str[,count=0])也能实现re.sub的功能。
不同之处在于,subn会返回替换后的字符串和替换的次数,将上述代码用subn演示,就如下所示:
import re
regex = re.compile("(?:GC){3,}") # 匹配至少3个GC结边的字符串
seq = "ATGATCGTACTGCGCGCTTCATGTGATGCGCGCGCGCAGACTATAAG"
print("Before:", seq)
print("After:", regex.subn("",seq))
结果如下所示:
C:Users20161111>python test.py
Before: ATGATCGTACTGCGCGCTTCATGTGATGCGCGCGCGCAGACTATAAG
After: ('ATGATCGTACTTTCATGTGATAGACTATAAG', 2)
12.
正则表达式在生物信息学方面有什么用处?
答:正则表达式可以用于搜索PROSITE(这是一个蛋白质拉点和序列模式数据库),这个数据库的信息模式就是序列与描述序列的字符串。例如下面的这段字符串:
K-[KR]-C-G-H-[LMQR],这段字符串表示的是异柠檬酸酶的活性位点。具体的每个字母含义如下:
位于第1个位置的是K,位于第2个位置提是K或R,随后是CGH,最后是一段氨基酸序列,即L,M,Q或R。如果要在这个序列中搜索,必须要把PROSITE的格式转化为符合Python正则表达式的表示方式,就像这样K[KR]CGH[LMQR]。
为了将PROSITE转化为REGEX的基本格式,这个过程中包括移除连接符(“-”),将括号之间的数字替换为大括号之间的数字,并将“x”替换为点号,接着看一个腺苷酸环化酶相关蛋白2(
adenylyl cyclase associated protein 2)的例子。
此蛋白在PROSITE中的版本如下:
[LIVM](2)-x-R-L-[DE]-x(4)-R-L-E,这种序列是一致性模式(Consensus
pattern)。
其中,L是亮氨酸,I是异亮氨酸,V是缬氨酸,M是甲硫氨酸,x代表任意氨基酸,R是精氨酸,D是天冬氨酸,E是谷氨酸。
REGEX(正则表达式)版本如下:
[LIVM]{2}.RL[DE].{4}RLE
Example8:在FASTA格式中搜索蛋白质的模式
现在假设我们要在一个FASTA格式的文件中寻找这个模式。除了要找到这个模式外,我们有可能还需要在上下文中检索它的位置,即位于在这个模式之前与之后的10个氨基酸序列(代码中用小写字母表示),下面是一个Fasta格式的文件:
>Q5R5X8|CAP2_PONPY CAP 2 - Pongo pygmaeus (Orangutan).
MANMQGLVERLERAVSRLESLSAESHRPPGNCGEVNGVIGGVAPSVEAFDKLMDSMVAEFLKNSRILAGDVETHAEMVHSAFQAQRAFLLMASQYQQPHENDVAALLKPISEKIQEIQTFRERNRGSNMFNHLSAVSESIPALGWIAVSPKPGPYVKEMNDAATFYTNRVLKDYKHSDLRHVDWVKSYLNIWSELQAYIKEHHTTGLTWSKTGPVASTVSAFSVLSSGPGLPPPPPPPPPPGPPPLLENEGKKEESSPSRSALFAQLNQGEAITKGLRHVTDDQKTYKNPSLRAQGGQTRSPTKSHTPSPTSPKSYPSQKHAPVLELEGKKWRVEYQEDRNDLVISETELKQVAYIFKCEKSTLQIKGKVNSIIIDNCKKLGLVFDNVVGIVEVINSQDIQIQVMGRVPTISINKTEGCHIYLSEDALDCEIVSAKSSEMNILIPQDGDYREFPIPEQFKTAWDGSKLITEPAEIMA
下面的代码实现的就是这个功能,即在1个FASTA文件中寻找这个模式,代码如下:
import re
pattern = "[LIVM]{2}.RL[DE].{4}RLE"
fh = open('D:/prot.fas')
fh.readline()
seq = ""
for line in fh:
seq += line.strip()
rgx = re.compile(pattern)
result = rgx.search(seq)
patternfound = result.group()
span = result.span()
leftpos = span[0]-10
if leftpos < 0:
leftpos = 0
print(seq[leftpos:span[0]].lower() + patternfound + seq[span[1]:span[1]+10].lower())
fh.close()
运行代码如下所示:
C:Users20161111>python test.py
manmqgLVERLERAVSRLEslsaeshrpp
Example9:
清洗序列
正则表达式在清除序列方面更加常用,需要清理的序列通常是一些非标准的序列,就像下面的这样:
1 ATGACCATGA TTACGCCAAG CTCTAATACG ACTCACTATA GGGAAAGCTT GCATGCCTGC
61 AGGTCGACTC TAGAGGATCT ACTAGTCATA TGGATATCGG ATCCCCGGGT ACCGAGCTCG
121 AATTCACTGG CCGTCGTTTT
这个序列里面有空格,有数字,这些都不是我们所需要的,需要把它们的清除掉,清除序列的代码如下所示:
import re
regex = re.compile(' |d|n|t') # 有一个空格
seq = ''
for line in open('D:/pMOSBlue.txt'):
seq += regex.sub('',line)
print(seq)
结果如下所示:
C:Users20161111>python test.py
ATGACCATGATTACGCCAAGCTCTAATACGACTCACTATAGGGAAAGCTTGCATGCCTGCAGGTCGACTCTAGAGGATCTACTAGTCATATGGATATCGGATCCCCGGGTACCGAGCTCGAATTCACTGGCCGTCGTTTT
代码解释:最重要的就是这个模式:regex
= re.compile(' |d|n|t'),其中'
|d|n|t'表示的是,数字或换行,或空格。