regex - 如何使用正则表达式和R正确编辑字符串?

标签 regex r list vector dataframe

我将数据从制表符分隔的文本文件导入到 data.frame 中。现在我想调整和编辑名为 C1 的列的内容。为此目的,向我推荐了正则表达式。起初我使用:

for (rn in 1:length(C1))
C1s <- strsplit(as.character(C1[rn]), "; ", fixed = TRUE)[[1]]

分隔示例中的各个条目,例如:

  • [张俊岭]中国农业大学资源与环境科学学院,北京 100094,人民路中国; [张俊岭] Univ Hohenheim, Inst Plant Nutr, D-7000 Stuttgart, 德国; [乔治,埃克哈德]洪堡大学,裁剪科学研究所,植物营养系,D-14979 Grossbeeren,德国; [George, Eckhard] Leibniz Inst 蔬菜和观赏裁剪 Theodor,D-14979 Grossbeeren,德国
  • 多特蒙德大学,INST PHYS,D-44221 多特蒙德,德国;洪堡大学,INST PHYS,D-15738 德国策伊滕
  • 基尔大学,化学系,基尔 ST5 5BG,工作人员,英国; MT 西奈医院、MT 西奈 SCH MED、DR A A FISHBERG CTR NEUROBIOL,纽约,NY 10029;柏林洪堡大学,慈善医院,PATHOL 和 CLIN 生物化学系,柏林,德国
  • NIFAD,MOLEC 微生物实验室,贝塞斯达,医学博士

然后我想

  • 将所有内容设置为大写
  • 将字符串“Humboldt...Germany”替换为“HUMBOLDT”,将字符串“England”、“Scotland”、“Wales”和“North Ireland”替换为“UNITED KINGDOM”
  • 将美国州缩写和邮政编码的组合替换为“USA”
  • 将美国州缩写替换为“USA”

此外,我想删除除分号(包括分号后面的空格)、它们前面的单词以及上面示例中的最后一个单词之外的所有内容。
我用过

gsub('[.*\\] ', ''(toupper(C1s))  

gsub(',\\s*', ','(toupper(C1s))  

,例如,但无法使其正常工作。
我想得到以下输出:

  • 人民与中国;德国;洪堡;德国
  • 德国;洪堡
  • 英国;美国;洪堡
  • 美国

所以我的问题是:我怎样才能达到我想要的结果?
预先非常感谢您的考虑!

更新和其他问题

感谢 mrdwab 的有用回复和评论,我取得了很大进展。

不幸的是,直到现在我才意识到还有这样的地址,方括号中包含多个作者。不幸的是,mrdwab 提出的算法不能正确处理这些问题。

> test = c("[Bocquet, F. C.; Giovanelli, L.; Abel, M.; Porte, L.; Themlin, J. -M.] Aix Marseille Univ, Inst Mat Microelect & Nanosci Prov IM2NP, F-13397 Marseille 20, France; [Bocquet, F. C.; Giovanelli, L.; Abel, M.; Porte, L.; Themlin, J. -M.] CNRS, Inst Mat Microelect & Nanosci Prov IM2NP, UMR 6242, Marseille, France; [Amsalem, P.; Koch, N.] Humboldt Univ, Inst Phys, D-12489 Berlin, Germany; [Petaccia, L.; Topwal, D.; Gorovikov, S.; Goldoni, A.] Sincrotrone Trieste, I-34149 Trieste, Italy")

这是我得到的结果:

> test
[1] "[BOCQUET,  F. C." "GIOVANELLI,  L."  "ABEL,  M."        "PORTE,  L."      
[5] "FRANCE"           "[BOCQUET,  F. C." "GIOVANELLI,  L."  "ABEL,  M."       
[9] "PORTE,  L."       "FRANCE"           "[AMSALEM,  P."    "HUMBOLDT"        
[13] "[PETACCIA,  L."   "TOPWAL,  D."      "GOROVIKOV,  S."   "ITALY" 

这是我想要得到的结果:

[1] "FRANCE"; "FRANCE"; "HUMBOLDT"; "ITALY"

我尝试使用它来单独删除每个方括号及其内容:

C1s = gsub("(.*)[(.*)]", "\\2", C1s)

但是第一个左括号和最后一个右括号之间的所有内容都被删除了...... 如果我先用逗号替换方括号内的所有分号,也许会起作用?我试过了

C1s = gsub("[(.*);(.*)]", "[(.*),(.*)]", C1s)

实现这一目标,但没有成功。
因此,我非常感谢您在这方面的帮助!

除此之外,我仍然遇到另一个障碍,不幸的是,我似乎无法独自解决这个障碍......
这是我当前的输出:

> C1s
[1] "PEOPLES R CHINA" "GERMANY"         "HUMBOLDT"         "GERMANY"
[5] "GERMANY"         "HUMBOLDT"        "UNITED KINGDOM"   "USA"
[9] "HUMBOLDT"        "USA"
> dims
[1] 4 2 3 1
> is.list(C1)
[1] FALSE
> is.vector(C1)
[1] TRUE

但是我到底如何使用dims中的信息来创建所需的输出?:

[1] "PEOPLES R CHINA"; "GERMANY"; "HUMBOLDT"; "GERMANY"
[2] "GERMANY"; "HUMBOLDT"
[3] "UNITED KINGDOM"; "USA"; "HUMBOLDT"
[4] "USA"

提前非常感谢您的支持!

最佳答案

假设您的数据如下所示:

test = c("[Zhang, Junling] China Agr Univ, Coll Resources & Environm Sci, Beijing 100094, Peoples R China", 
         " [Zhang, Junling] Univ Hohenheim, Inst Plant Nutr, D-7000 Stuttgart, Germany", 
         " [George, Eckhard] Humboldt Univ, Inst Crop Sci, Dept Plant Nutr, D-14979 Grossbeeren, Germany", 
         " [George, Eckhard] Leibniz Inst Vegetable & Ornamental Crops Theodor, D-14979 Grossbeeren, Germany"
)

首先,让我们将其全部大写:

test = toupper(test)

然后,我们将 HUMBOLDT...GERMANY 更改为 HUMBOLDT

test = gsub("(.*)(HUMBOLDT)(.*)", "\\2", test)

然后,我们提取字符串的最后一部分。

test = gsub("(.*), +([A-Z ]+$)", "\\2", test)
> test
[1] "PEOPLES R CHINA" "GERMANY"         "HUMBOLDT"        "GERMANY"    

如果我有一个更完整的示例,我也许也能帮助您完成其他部分。

更新

这是一个最有效的解决方案,应该可以帮助您弄清楚该怎么做。

使用“扫描”从您的帖子中复制数据,我们可以获得如下所示的数据:

test = c("[Zhang, Junling] China Agr Univ, Coll Resources & Environm Sci, Beijing 100094, Peoples R China; [Zhang, Junling] Univ Hohenheim, Inst Plant Nutr, D-7000 Stuttgart, Germany; [George, Eckhard] Humboldt Univ, Inst Crop Sci, Dept Plant Nutr, D-14979 Grossbeeren, Germany; [George, Eckhard] Leibniz Inst Vegetable & Ornamental Crops Theodor, D-14979 Grossbeeren, Germany", 
         "UNIV DORTMUND,INST PHYS,D-44221 DORTMUND,GERMANY; HUMBOLDT UNIV,INST PHYS,D-15738 ZEUTHEN,GERMANY", 
         "UNIV KEELE,DEPT CHEM,KEELE ST5 5BG,STAFFS,ENGLAND; MT SINAI HOSP,MT SINAI SCH MED,DR A A FISHBERG CTR NEUROBIOL,NEW YORK,NY 10029; HUMBOLDT UNIV BERLIN,CHARITE HOSP,DEPT PATHOL & CLIN BIOCHEM,BERLIN,GERMANY", 
         "NIFAD,MOLEC MICROBIOL LAB,BETHESDA,MD")

您需要一步一步地进行才能实现您想要的转变。我就是这样做的。

test.orig = test # A backup, just in case
test = toupper(test) # To uppercase
test = strsplit(test, ";") # Split everything up into a list
dims = sapply(test, length) # We might need this later
test = unlist(test) # Now, a single vector
test = gsub(",", " , ", test) # Pad those commas with some space
# Replace any 'HUMBOLDT'...'GERMANY' stuff with 'HUMBOLDT'
test = gsub("(.*)(HUMBOLDT)(.*)(GERMANY$)", "\\2", test)
# Replace a bunch of stuff with 'UNITED KINGDOM'
test = gsub("ENGLAND|SCOTLAND|WALES|NORTH IRELAND", "UNITED KINGDOM", test)
# Search for a pair of letters followed by a space followed by five digits
# and replace it with USA
test = gsub(" [A-Z]{2} [0-9]{5}", " USA", test)
# Find the item following the last comma
test = gsub("(.*), ([A-Z ]+)$", "\\2", test)
# Remove any whitespace
test = gsub("^ | $", "", test)
> test
[1] "PEOPLES R CHINA" "GERMANY"         "HUMBOLDT"        "GERMANY"        
[5] "GERMANY"         "HUMBOLDT"        "UNITED KINGDOM"  "USA"            
[9] "HUMBOLDT"        "MD"                  
# Unlist it if you need to
> split(test, rep(dims, dims))
$`1`
[1] "MD"

$`2`
[1] "GERMANY"  "HUMBOLDT"

$`3`
[1] "UNITED KINGDOM" "USA"            "HUMBOLDT"      

$`4`
[1] "PEOPLES R CHINA" "GERMANY"         "HUMBOLDT"        "GERMANY"   

但是,我将留给您解决如何用 USA 替换州缩写以及如何将其放回同一行顺序的任务。

关于regex - 如何使用正则表达式和R正确编辑字符串?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10479132/

相关文章:

javascript - 正则表达式小组赛

r - 如果所有汇总值均为 NA,则 dplyr 汇总保留 NA

python - 列表上的 Django lte/gte 查询

c# - 合理数量的 List <string> 元素?

list - Haskell - 如何创建矩阵

regex - 用于从 MDX 查询中提取元素的正则表达式

mysql - 使用正则表达式仅获取数字

asp.net - 重复正则表达式

r - 将 `dplyr::filter_at` 与多个谓词表达式一起使用

在函数内部和外部创建的 ggplot2 对象之间的 RDS 文件大小差异