具有各种模式的复杂正则表达式匹配

时间:2018-10-02 11:54:07

标签: r regex

我有一个数据框,其中的一列包含以下信息:

    c("GYRA.Flq_NC_002695.1.916822_Fluoroquinolones_Fluoroquinolone_resistant_DNA_topoisomerases_GYRA_RequiresSNPConfirmation", 
"GYRB.CARD_pvgb_AP009048_3760295_3762710_ARO_3003303_Escherichia_Fluoroquinolones_Fluoroquinolone_resistant_DNA_topoisomerases_GYRB_RequiresSNPConfirmation", 
"MARR.CARD_pvgb_U00096_1619119_1619554_ARO_3003378_Escherichia_Multi_drug_resistance_MDR_regulator_MARR_RequiresSNPConfirmation", 
"PARC.Flq_M58408_gene_Fluoroquinolones_Fluoroquinolone_resistant_DNA_topoisomerases_PARC_RequiresSNPConfirmation", 
"SOXS.CARD_pvgb_U00096_4277468_4277933_ARO_3003381_Escherichia_Multi_drug_resistance_MDR_regulator_SOXS_RequiresSNPConfirmation", 
"TOLC.CARD_phgb_FJ768952_0_1488_ARO_3000237_tolC_Multi_drug_resistance_Multi_drug_efflux_pumps_TOLC", 
"parE.CARD_pvgb_NC_007779_3172159_3174052_ARO_3003316_Escherichia_Fluoroquinolones_Fluoroquinolone_resistant_DNA_topoisomerases_parE_RequiresSNPConfirmation", 
"GYRA.Flq_CP001918.1_gene3562_Fluoroquinolones_Fluoroquinolone_resistant_DNA_topoisomerases_GYRA_RequiresSNPConfirmation", 
"PARC.Flq_NC_003197.1.1254697_Fluoroquinolones_Fluoroquinolone_resistant_DNA_topoisomerases_PARC_RequiresSNPConfirmation", 
"GYRA.Flq_NC_003197.1.1253794_Fluoroquinolones_Fluoroquinolone_resistant_DNA_topoisomerases_GYRA_RequiresSNPConfirmation", 
"parE.CARD_pvgb_NC_003197_3343961_3345854_ARO_3003317_Salmonella_Fluoroquinolones_Fluoroquinolone_resistant_DNA_topoisomerases_parE_RequiresSNPConfirmation", 
"ACRR.CARD_pvgb_NC_014121_1270697_1271351_ARO_3003374_Enterobacter_Multi_drug_resistance_MDR_regulator_ACRR_RequiresSNPConfirmation"
)

我要做的是在上面每个条目中获取特定的ID号,在下面标记,然后为数据框中的每一行创建一个新列,并使用该数字创建新列。

“ GYRA.Flq_ NC_002695.1.916822 _Fluoroquinolones_Fluoroquinolone_耐药性_DNA_topoisomerases_GYRA_RequiresSNP确认”, “ GYRB.CARD_pvgb_ AP009048_3760295_3762710 _ARO_3003303_Escherichia_Fluoroquinolones_Fluoroquinolone_proof_DNA_topoisomerases_GYRB_RequiresSNP确认”, “ MARR.CARD_pvgb_ U00096_1619119_1619554 _ARO_3003378_Escherichia_Multi_drug_resistance_MDR_regulator_MARR_RequiresSNP确认”, “ PARC.Flq_ M58408 _gene_Fluoroquinolones_Fluoroquinolone_耐药性_DNA_topoisomerases_PARC_RequiresSNP确认”, “ SOXS.CARD_pvgb_ U00096_4277468_4277933 _ARO_3003381_Escherichia_Multi_drug_resistance_MDR_regulator_SOXS_RequiresSNP确认”, “ TOLC.CARD_phgb_ FJ768952_0_1488 _ARO_3000237_tolC_Multi_drug_resistance_Multi_drug_efflux_pumps_TOLC”, “ parE.CARD_pvgb_ NC_007779_3172159_3174052 _ARO_3003316_Escherichia_Fluoroquinolones_Fluoroquinolone_proof_DNA_topoisomerases_parE_RequiresSNPConfirmation”, “ GYRA.Flq_ CP001918.1 _gene3562_Fluoroquinolones_Fluoroquinolone_耐药性_DNA_topoisomerases_GYRA_RequiresSNP确认”, “ PARC.Flq_ NC_003197.1.1254697 _Fluoroquinolones_Fluoroquinolone_耐药性_DNA_topoisomerases_PARC_RequiresSNP确认”, “ GYRA.Flq_ NC_003197.1.1253794 _Fluoroquinolones_Fluoroquinolone_耐药性_DNA_topoisomerases_GYRA_RequiresSNP确认”, “ parE.CARD_pvgb_ NC_003197_3343961_3345854 _ARO_3003317_Salmonella_Fluoroquinolones_Fluoroquinolone_proof_DNA_topoisomerases_parE_RequiresSNPConfirmation”, “ ACRR.CARD_pvgb_ NC_014121_1270697_1271351 _ARO_3003374_Enterobacter_Multi_drug_resistance_MDR_regulator_ACRR_RequiresSNP确认”

我尝试了以下命令:

library(dplyr)
df %>% mutate(ref_name2 = sub("[A-z]+.[A-z]+.[A-z]+.([A-z][A-z].[0-9]+.[0-9].[0-9]+)", "\\1", ref_name),
         ref_name2 = sub("\\_ARO.*", "", ref_name2),
         ref_name2 = sub("\\_Fluoro.*", "", ref_name2),
         ref_name2 = sub("\\_gene.*", "", ref_name2))

但这仅部分匹配上述字符串,并且还删除了一些我想要的字母。有比多个sub / gsub调用更简单的方法吗?

我想结束的事情:

c(NC_002695.1.916822, AP009048_3760295_3762710, U00096_1619119_1619554, M58408, U00096_4277468_4277933, FJ768952_0_1488, NC_007779_3172159_3174052, CP001918.1, NC_003197.1.1254697, NC_003197.1.1253794, NC_003197_3343961_3345854, NC_014121_1270697_1271351)

我尝试在https://regexr.com/30u4a上进行视觉匹配,并且还尝试阅读许多有关复杂匹配的内容,但似乎找不到正确的代码。

2 个答案:

答案 0 :(得分:5)

您可以使用

> sub("^.*?_([A-Z]+[0-9_.]*[0-9]).*", "\\1", x)
 [1] "NC_002695.1.916822"        "AP009048_3760295_3762710"  "U00096_1619119_1619554"    "M58408"                    "U00096_4277468_4277933"    "FJ768952_0_1488"          
 [7] "NC_007779_3172159_3174052" "CP001918.1"                "NC_003197.1.1254697"       "NC_003197.1.1253794"       "NC_003197_3343961_3345854" "NC_014121_1270697_1271351"

请参见regex demo

模式详细信息

  • ^-字符串的开头(由于使用了sub,因此可以省略)
  • .*?-零个或多个字符,并尽可能少(请注意,此处不可能使用[^_]*,因为我们需要的模式可能会出现在0个或多个下划线之后)
  • _-一个_
  • ([A-Z]+[0-9_.]*[0-9])-捕获组1:
    • [A-Z]+-1个以上大写ASCII字母
    • [0-9_.]*-0个或更多数字,_.字符
    • [0-9]-一个数字
  • .*-字符串的其余部分。

答案 1 :(得分:0)

我能做的最好的事情是this example

"[A-Za-z]*\.([A-Za-z]*_)*([A-Z]+_?\d+(_\d+(_\d+)*|\.\d+(\.\d+)*)?)[^"]*"

这意味着,搜索左双引号",然后搜索一组字母,然后搜索点.,然后搜索可变数量(可能为空)的字母序列(任何情况)依次用下划线_和我们感兴趣的组(组\2

  • 一系列字母,后跟(可选)下划线,然后是
    • 由下划线分隔的一组数字序列,或
    • 一组数字组,由点.隔开。

,然后跟在下一个双引号上,关闭字符串。

如果用以下字符串进行全局替换:

\\2

然后,您将获得所需的结果,如上面的演示所示。