前言
对于生信学习,正则表达式超级重要,超级重要,超级重要
开始的时候,可能不知道它的定义,但是知道它怎么用,比如简单的:
ls -la *.log
-rw-rw-r--. 1 w w 774 Mar 30 16:45 1.log
-rw-rw-r--. 1 w w 774 Mar 30 16:51 2.log
-rw-rw-r--. 1 w w 774 Mar 30 16:51 3.log
-rw-rw-r--. 1 w w 636 Mar 30 18:40 4.log
*.log
会让ls
命令只对 什么什么.log 形式的文件执行,至于 .log 之前有多少个字符都OK。这是使用正则表达式的 规则 来 匹配 需要的 文本内容 或 字符 的一个简单应用。
定义
正则表达式是你所定义的模式模板(pattern template),Linux工具可以用它来过滤文本。Linux工具(比如sed编辑器或gawk程序)能够在处理数据时使用正则表达式对数据进行模式匹配。如果数据匹配模式,它就会被接受并进一步处理;如果数据不匹配模式,它就会被滤掉。
正则表达式是一种规则,实现方法很多,很难用一个简洁的描述来涵盖所有可能。
使用正则表达式最大的问题在于有不止一种类型的正则表达式。Linux中的不同应用程序可能会用不同类型的正则表达式。这其中包括编程语言(Java、Perl和Python)、Linux实用工具(比如sed编辑器、gawk程序和grep工具)以及主流应用(比如MySQL)
正则表达式是通过正则表达式引擎(regular expression engine)实现的。正则表达式引擎是一套底层软件,负责解释正则表达式模式并使用这些模式进行文本匹配。在Linux中,有两种流行的正则表达式引擎:
- POSIX基础正则表达式(basic regular expression,BRE)引擎
- POSIX扩展正则表达式(extended regular expression,ERE)引擎
总结一下书上的东西
-
正则表达式
- REGEXP:Regular Expressions,由一类特殊字符及文本符编写的模式,其中有些字符(元字符)不表示字符字面意思,而表示控制或通配的功能
- 程序支持:
grep
,sed
,awk
,vim
,less
,nginx
,varnish
……等 - 分两类:基本正则表达式;扩展正则表达式;grep -E , egrep
- 正则表达式引擎:采用不同算法,检查处理正则表达式的软件模块;PRCE(Perl Compatible Regular Expressions)
- 元字符分类:字符分类、匹配次数、位置锚定、分组
- man 7 regex (没错,可以查看文档)
-
字符匹配
.
匹配任意单个字符[]
匹配指定范围内的任意单个字符,示例:[wan] [0-9] [a-z] [a-zA-Z]
[^]
匹配指定范围外的任意单个字符[:alnum:]
字母和数字[:alpha:]
代表任何英文大小写字符,即[A-Za-z]
[:lower:]
[:upper:]
小写、大写字母[:blank:]
空白字符(空格和制表符)[:space:]
水平和垂直的空白字符(比[:blank:]
范围广)[:cntrl:]
不可打印的控制字符(退格、删除等)[:digit:]
[:xdigit:]
十进制数字、十六进制数字[:graph:]
可打印的非空白字符[:print:]
可打印的字符[:punct:]
标点符号PS:示例
cat /etc/passwd|grep "[[:punct:]]"
-
匹配次数:要用在想要匹配的字符后面
*
匹配任意次数,包括0次.*
任意长度的任意字符?
匹配前面的字符0或1次+
匹配其前面的字符至少1次{n}
匹配前面的字符n次{m,n}
匹配前面的字符至少m次,最多n次{,n}
匹配到前面的字符至多n次{m,}
匹配到前面的字符至少m次 -
位置锚定:定位字符位置
^
行首锚定,用于模式的最左侧$
行尾锚定,用于模式的最右侧^PARTTERN$
:用于模式匹配的整行^$
空行^[[:space:]]$
空白行
\<
或\b
词首锚定,用于单词模式的左侧,其后出现的内容必须作为单词首部\>
或\b
词首锚定,用于单词模式的右侧,其前出现的内容必须作为单词词尾,没错是\b
,在需要匹配的东西的左或者右,作用不同 -
分组:
()
()
将一个或多个字符捆绑到一起,当作一个整体处理,如:(root)+
分组括号中的模式匹配到的内容会被正则表达式引擎记录于内部的变量中,这些变量的命名方式为:
\1
,\2
,\3
,……\1
表示从左侧起第一个左括号以及与之匹配的右括号之间的模式所匹配到的字符示例
(string1+(string2)*)
\1
: string1+(string2)\2
: string2后向引用:引用前面的分组括号中模式所匹配的字符,而非模式本身
或者:
|
示例a|b
a 或 bC|cat
C 或cat(C|c)at
cat 或 Cat -
egrep及扩展正则表达式
egrep = grep -E
字符匹配:
.
任意单个字符;[]
指定范围字符;[^]
不在指定范围字符次数匹配(匹配前面字符):
*
任意次;?
0或1次;+
一或多次;{m}
匹配m次;{m,n}
至少m次至多n次位置锚定:
^
行首;$
行尾 ;\< \b
词(语)首;\> \b
词(语)尾分组:
()
;后向引用\1
\2
……或 :
a|b
a 或b ;C|cat
C或cat;(C|c)at
Cat或cat -
………
纸上得来终觉浅,绝知此事要躬行
一个简单的使用例子,单细胞转录组上有分析的时候,公司返回的单细胞测序文件名称往往不符合cellranger
的输入需求,需要按照cellranger
规定的文件名字,重命名原始文件。加入有这样一批公司返回的文件:
Jj22090-1_R1.fastq.gz; Jj22090-1_R2.fastq.gz
Jj22090-2_R1.fastq.gz; Jj22090-2_R2.fastq.gz
Jj22090-3_R1.fastq.gz; Jj22090-3_R2.fastq.gz
需要改成:Sample_S1_L00X_R1_001.fastq.gz
使用rename
配合正则表达式更改,思路是这样的,先将不变的部分分组(使用括号),然后分好的组中,填入可以表征组内内容的表达式,样本名称不变:“Jj22090”为一组,由不同字符组成,可表征为任意多个字符.*
;样本独特序号不变:“-”后面的数字为一组,可表征为0-9的数字[0-9]
;Read1和Read2的标识不变:“R”以及后面的数字为一组,可表征为[1-2]
;那么,原始的名字可以表达为:(.*)-([0-9])_(R[1-2]).fastq.gz
,开始更改,原始名字不变的部分为$1$2$3
,加上下划线啊、L001啊,就变成:$1_S$2_L001_$3_001.fastq.gz
,配合 rename
命令:
rename 's/(.*)-([0-9])_(R[0-9]).fastq.gz/$1_S$2_L001_$3_001.fastq.gz/' *.gz
改名为:
Jj22090_S1_L001_R1_001.fastq.gz; Jj22090_S1_L001_R2_001.fastq.gz
Jj22090_S2_L001_R1_001.fastq.gz; Jj22090_S2_L001_R2_001.fastq.gz
Jj22090_S3_L001_R1_001.fastq.gz; Jj22090_S3_L001_R2_001.fastq.gz
闲聊
本来上个礼拜就想把笔记发出来,然后我阳了……所以拖到了现在。关于正则表达式,其实学起来,没那么难,而且学会了一种或者一个语言的之后,基本就是会一个,个个都会了,比如会了Linux的,之后R的python的等等,一点就通,当然,内容也大同小异。就像一块儿蛋糕,你不吃就不知道啥味道,嗯……订个蛋糕吃吃吧😑