正则表达式

正则表达式(regular expression)是用一系列字符串去表示一个搜索的模式(pattern)的, 符合该匹配的字符串将被作为搜索结果。使用正则表达式可以完成复杂的文本处理任务。

寻找字符串的模式及找规律,例如,sunday,monday,tuesday的规律是若干个 字符后面有三个一样的字符“day”,那么模式可以表示为(sun | mon | tues)day

正则表达式基本概念

正则表达式在不同的语言有相同或者相似的实现,也有不同语言的特色,同时 POSIX规定的正则表达式有基础正则表达式和扩展正则表达式之分,但是大多数 的正则表达式都包括:或(or),分组(group),数量(quantification), 通配符(wildcard)等。

grep 默认支持的是基础正则表达式,grep -E 或者 egrep 支持的是扩展 正则表达式。两者有一定区别,使用时需要稍稍注意。

  • 或:字符串符合若干模式中的一种,在正则表达式中一般以 pattern1 | pattern2 来表示。例如:sunday | saturday 可以用来匹配 “sunday” 或 者 “saturday”。在基础正则表达式中是使用 \| 来表示或的,|则表示该符 号本身。在扩展正则表达式中则反过来,|是表示或的,\|表示该符号。
$ echo sunday | grep "sunday\|saturday"
sunday
$ echo sunday | grep "sunday|saturday"
$ echo "sunday|" | grep "sunday|saturday"
$ echo monday | grep "sunday\|saturday"
$ echo sunday | egrep "sunday\|saturday"
$ echo sunday | egrep "sunday|saturday"
sunday
  • 分组:对于一个表达式中的一部分进行分组,可以在后面只输出分组中 的内容,一般用小括号(pattern)表示分组。例如:(sun|mon|tues)day, 使用分组可以把要匹配的可变部分和后面不可变的部分进行区分。许多语言也 支持把小括号中的匹配单独输出,例如去匹配 “sunday” 并输出分组中的内容 的时候就可以输出 “sun”,而去匹配 “tuesday” 的时候可以输出分组内容 “tues”。一个正则表达式中可以有多个分组,一些语言也支持把多个分组选择 性输出。在基础正则表达式中是使用 \(\) 来表示分组的,()则表示小括 号本身。在扩展正则表达式中则反过来,()是表示分组的,\(\)表示小括 号。
$ echo sunday | grep "\(sun\|satur\)day"
sunday
$ echo "sunday" | egrep "(sun|satur)day"
sunday
$ echo "sunday" | grep "(sun|satur)day"
$ echo "monday" | egrep "(sun|satur)day"
  • 数量:使用数量匹配符号,可以对其前面的字符指定匹配的数量。
  • ?:匹配零个或一个字符,例如 “ab?c” 匹配的只会是 “ac”,“abc”
  • *:匹配零个或多个字符,例如 “ab*c” 匹配的会是 “ac”,“abc”,“abbc”,“abbbc”等等。
  • +:匹配一个或多个字符,例如 “ab+c” 匹配的会是 “abc”,“abbc”,“abbbc”,“abbbbc”等等
  • {n}:匹配 n 个字符,例如 “a{3}bc” 只会匹配 “aaabc”
  • {min,}:匹配最少 min 个字符,例如 “ab{3,}c” 会匹配 “abbbc”,“abbbbc”,“abbbbbc” 等等。 “ab{0,}c” 相当于 “ab*c”;“ab{1,}c” 相当于“ab+c”。
  • {min,max}:匹配最少 min 个字符,最多 max 个字符,例如 “ab{3,6}c” 只会匹配 “abbbc”,“abbbbc”,“abbbbbc”,“abbbbbbc”。“ab{0,1}c”相当 于“ab?c”。
  • 类似前面,在基础正则表达式中,\{\} 用来作为正则表达式。在扩展正则表达式中则相反,使用 {}
$ echo "AGCGTTTTGT" | egrep "T{4,}"
AGCGTTTTGT
$ echo "AGCGTTTTGT" | egpre "GT+G"
AGCGTTTTGT
  • 通配符:有的时候我们需要抓取的字符的组合非常多,这个时候就需要使用通 配符,而不需要把所有组合都自己打出来。利用通配符,我们可以使用一个记 号去表示多种字符。需要注意的是,不管通配符本身包含多少字符,通配符自 己只会匹配一个字符。
  • .:可以匹配任何单个字符。
  • []:匹配中括号中包括的所有字符,例如 [a123.],可以匹配 “a”, “1”,“2”,“3”,“.”。[a-z]匹配所有的小写字母,[A-Z]匹配所有的大 写字母,[0-9]匹配所有的数字。
  • [^]:匹配不在中括号中的其他字符,例如 [^a1],匹配除了 “a” 和 “1” 之外的其他字符。
  • [:upper:]:匹配所有大写字母,相当于 [A-Z]
  • [:lower:]:匹配所有小写字母,相当于 [a-z]
  • [:alpha:]:匹配所有大写和小写字母,相当于 [[:upper:][:lower:]]
  • [:alnum:]:匹配所有的大小写字母和数字,相当于 [[:alpha:][:digit:]]
  • [:digit:]:匹配所有的数字 [0-9]
  • [:xdigit:]:匹配十六进制数字 [0-9A-Fa-f]
  • [:punct:]:匹配标点符号 [.,!?:…]
  • [:blank:]:匹配空格和制表符 [ \t]
  • [:space:]:匹配空白字符,空格,制表符,回车,新行,新页等,相当于[ \t\n\r\f\v]
  • [:cntrl:]:控制字符。
  • [:graph:]:能看得到的字符,相当于[^ \t\n\r\f\v]
  • [:print:]:可打印字符,能看得到的字符和空格 [^\t\n\r\f\v]
$ cat sample.fq | grep "ACCG([ATCG]{20})GTTT" > reads_with_sgRNA.txt

对于字符串开头和结尾,可以使用 ^ $ 来进行定位。

  • ^:指定字符串起始位置
  • $:指定字符串结束位置
$ echo "one two three" | grep "two"
one two three
$ echo "one two three" | grep "^two"
$ echo "one two three" | grep "^one"
one two three
$ echo "one two three" | grep "three$"
one two three
By @Wolfson Liu in
Tags : #regular expression,