如何用正则表达式匹配括号中的内容。

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何用正则表达式匹配括号中的内容。相关的知识,希望对你有一定的参考价值。

“()” 等这些在正则表达式中有特殊意义的字符,要当普通字符使用时,在其前面加'\\'即可。

正则表达式中的圆括号的作用:

    正则表达式中的圆括号的作用是对字符进行分组,并保存匹配的文本。

    圆括号用法I:对字符或元字符进行分组,这样在圆括号内就可以对字符组合使用限定符。

    eg. 匹配A+一个数字+A+一个数字:(A\\d)2

    圆括号用法II:表示可选择性。

    3.1 从两个直接量中选择一个。

    eg. gr(a|e)y匹配gray和grey,该例子还可以使用gr[ae]y,字符类效率更高。

    3.2 从多个直接量中选择。

    eg. (Doctor|Dr\\.?)匹配Doctor,Dr,Dr.三种情况。

    3.3 错误匹配的交替行为。

    使用交替行为时,有时会出现意想不到的错误。

    eg. 用(a|ab)匹配ab时,只能匹配a,但是如果用(ab|a),则可以匹配ab。

    反向引用(backreferences)。

    语法:.NET和javascript中,表示匹配第一组的变量被指定为”\\1”。

    能够体现反向引用的便利性的一种情况是找到句子中重复的单词。

    eg. 查找下列句子中重复的单词:

    I think that that is often overdone.

    This sentence contains contains a doubled word or two two.

参考技术A

String str = "void main(unsigned int para)";

String reg=".*\\\\s+([^\\\\s\\\\)]+)\\\\)$";

str=str.replaceAll(reg,"$1");

答果子问R语言如何用正则表达式提取特定的字符串

这个帖子是为了果子的一个提问

R语言能不能实现匹配括号里面的内容, 但是不包括括号

这个问题来自于他的一篇帖子, 里面提取字符串的代码不够简洁。

果子在原帖里面引用我的一句话,”正则表达式是我们认识这个世界的哲学”.既然我说了这句话,那么我就得贯彻我的哲学理念,在R里面用正则表达式把数据给提取了。

首先在https://www.ncbi.nlm.nih.gov/geo/query/acc.cgi?acc=GPL4381把对应的数据给下载了

【答果子问】R语言如何用正则表达式提取特定的字符串

然后用data.tablefread进行高效智能的读取数据

GPL4381 <- data.table::fread("GPL4381-4306.txt")

正则表达式的核心在于观察数据,提取模式,这也就是我说”正则表达式是我们认识这个世界的哲学”的原因,因为我们就是通过不断观察世界研究规律指导生活。

【答果子问】R语言如何用正则表达式提取特定的字符串

从上图中你发现了什么,是不是都是”xxxx(基因名),xxx”这种情况。

于是我们就可以通过R语言的regexpr提取上面基因名的位置信息了

pattern <- ".*\\((?<ID>[A-Za-z0-9]*)\\),.*"
result <- regexpr(pattern= pattern, text = GPL4381$GB_DEFINITION, perl=TRUE)

仔细观察下我的写的模式识别,pattern <- ".*\\((?<ID>[A-Za-z0-9]*)\\),.*", 你会发现我用到一个你未必见过的模式,(?<>),这是Perl 的正则表示系统里的模式,所以必须用perl=TRUE才能被R解读。它的作用就是把括号里面的模式单独分组。

regexpr会返回匹配的内容的起始位置,匹配长度。如果匹配, 位置为”-1”

start <- attr(result,"capture.start")
length <- attr(result,"capture.length")
name <- attr(result,"capture.name")

之后,我们可以用substr根据位置信息进行提取。

geneID <- ifelse(start > 0, 
                 substr(GPL4381$GB_DEFINITION, start[,name],start[,name] + length[,name]-1),NA)

最终你查看geneID的前10个的时候,你会发现就是你想要的

head(geneID,n=10)

当然如果你用stringr, 那代码其实更加简洁一些

res <- stringr::str_match(string = GPL4381$GB_DEFINITION, pattern = pattern)
geneID <- res[,2]
head(geneID)

说下核心知识点:

  • regexpr可以返回匹配的起始位置和匹配长度,返回-1表示没有匹配

  • (?<组名>匹配模式): 对匹配内容进行分组, 在perl=TRUE下使用。


题外话


R语言处理字符并非强项,当然有人激进地认为R甚至还不算是一门编程语言,所以如果要处理字符,更好的建议是用其他编程语言,如Perl, Python. 但是如果你只能用R语言的话,那么这里有几条建议


- 学习正则表达式。正则表达式(regular expression) 本质上是用一组符号来描述你的目标字符串, 但是由于各种原因,出现了许多流派。在使用正则表达式之前,你要明确你能用哪些元字符。不过还是推荐你看 https://r4ds.had.co.nz/strings.html 学stringr

- 最后一条,马上给我去看 https://r4ds.had.co.nz/strings.html 


还有,如果你怕自己一下子背不住那么多元字符,那么你可以 点开这个链接, https://github.com/rstudio/cheatsheets/blob/master/strings.pdf  下载PDF进行打印,每天看一遍。