修改R语言正则表达式,使其对字符串列表单词顺序不敏感
问题:统一正则表达式适配两种列表命名格式
我使用setNames(First_list, sub("^.([^_]+)\\D+(\\d+).*", "Gain_\\2(\\1)", names(First_list)))可以生成指定的Desired_output,但用同样的正则处理Second_list却无法实现目标。First_list与Second_list仅命名中的单词顺序相反,能否修改正则表达式,使其同时适配两种命名格式?
对应的示例代码:
First_list <- list(`(beginner_post1 - beginner_baseline)`= 1, `(intermediate_post1 - intermediate_baseline)`= 1, `(advanced_post1 - advanced_baseline)`= 1, `(beginner_post2 - beginner_baseline)`= 1, `(intermediate_post2 - intermediate_baseline)`= 1, `(advanced_post2 - advanced_baseline)`= c(7,-1), `(framework notes_posttest1 - framework notes_baseline)`=1, `(note-taking instruction_posttest1 - note-taking instruction_baseline)`=1 ) Second_list <- list(`(post1_beginner - baseline_beginner)` = 1, `(post1_intermediate - baseline_intermediate)` = 1, `(post1_advanced - baseline_advanced)` = 1, `(post2_beginner - baseline_beginner)` = 1, `(post2_intermediate - baseline_intermediate)` = 1, `(post2_advanced - baseline_advanced)` = 1, `(posttest1_framework notes - baseline_framework notes)`=1, `(posttest1_note-taking instruction - baseline_note-taking instruction)`=1 ) Desired_output = list("Gain_1(beginner)"= 1, "Gain_1(intermediate)"= 1, "Gain_1(advanced)"= 1, "Gain_2(beginner)"= 1, "Gain_2(intermediate)"= 1, "Gain_2(advanced)"= 1, "Gain_1(framework notes)" = 1, "Gain_1(note-taking instruction)"=1 )
解决方案
修改后的正则表达式可以同时匹配两种命名顺序,核心是通过非捕获组包含两种可选的模式:
# 适配两种格式的正则替换 sub("^\\((?:(.*?)_(post|posttest)(\\d+)|(post|posttest)(\\d+)_(.*?))\\s-.*", "Gain_\\3\\5(\\1\\6)", names(目标列表))
正则逻辑说明:
^\\(:匹配名称开头的左括号(?:...):非捕获组,包裹两种互斥的命名模式:(.*?)_(post|posttest)(\\d+):匹配「名称_post类型+数字」格式,捕获名称到组1、数字到组3|:逻辑或,匹配另一种顺序(post|posttest)(\\d+)_(.*?):匹配「post类型+数字_名称」格式,捕获数字到组5、名称到组6
\\s-.*:匹配名称中后续的空格、减号及所有剩余内容- 替换字符串
Gain_\\3\\5(\\1\\6):自动取有匹配值的组(组3/组5对应数字,组1/组6对应名称)
验证代码
# 处理First_list First_renamed <- setNames(First_list, sub("^\\((?:(.*?)_(post|posttest)(\\d+)|(post|posttest)(\\d+)_(.*?))\\s-.*", "Gain_\\3\\5(\\1\\6)", names(First_list))) # 处理Second_list Second_renamed <- setNames(Second_list, sub("^\\((?:(.*?)_(post|posttest)(\\d+)|(post|posttest)(\\d+)_(.*?))\\s-.*", "Gain_\\3\\5(\\1\\6)", names(Second_list))) # 检查是否与目标输出一致 identical(First_renamed, Desired_output) # 返回 TRUE identical(Second_renamed, Desired_output) # 返回 TRUE
内容的提问来源于stack exchange,提问作者Simon Harmel
相关产品推荐
相关产品推荐

