【问题标题】:extract a pattern from a text in R from a subset of patterns从模式子集中从 R 中的文本中提取模式
【发布时间】:2016-04-15 07:48:16
【问题描述】:

我有如下代码列表

ccode<-c('S','PD','CH','ML','MD','VA','BVI','DB','KD','KE','PW','COL','AD','MET','VP','SI','VR','GAO','LK','RP','PAD','WAN','PWD','PMP','PBR','VN','PPC','NK','K','AH','I','JP','JU','UDZ','CHM','DDN','LN','CL','CLH','DKM','GK','WD','ED','DDK','DLN','DRN','DFD','GZB','DVV','GUR','GGN','ND','HHN','HAS','HYD','HKP','BWF','BBW','BKM','BSN','BL','BIN','ST','KN')

现在,我想从下面的示例中提取一个以代码开头的字符串

consolidated_csv_v2 <- c("pt paid rs-8488/-  remaining amt","Credit Card Sales","ML 2926 VARSHA LAKHANI (AG)","IMRAN KHAN-PW-4798","Deepali Mishra Ah-5564 Tst", "MANJU S-11226 T","SNEHA S-16191","SUMIT SETHI AH-5747 AG","SUJATA VORA AH-5361 AG","Deepali Mishra Ah-5564 Tst")

数据分布在 477326 行

预期的输出是代码后跟数字。

str_extract(consolidated_csv_v2, "AH.*$")

[1] NA           NA           NA           NA           NA           NA          
[7] NA           "AH-5747 AG" "AH-5361 AG" NA  AG"

此公式仅适用于静态代码“AH”。我怎样才能对 ccode 中的任何代码进行相同的匹配。

【问题讨论】:

  • 请通过发布一些数据使您的示例可重现。
  • 你怎么会有代码'S'和代码'SI'?那么例如以 SA 开头的字符串?
  • @Andrie 更新了示例数据,它有什么帮助!!
  • @Sotos 是的,我知道这是一个挑战!至少我可以找出其他代码对吗?
  • 或许使用str_extract(consolidated_csv_v2[,4],paste0("^(", paste(ccode, collapse="|"),").*"))的模式

标签: r regex stringr


【解决方案1】:

我假设您需要在单词边界之后提取以“代码”开头并后跟连字符的子字符串。

然后,使用

 "\\b(?:S|PD|CH|ML|MD|VA|BVI|DB|KD|KE|PW|COL|AD|MET|VP|SI|VR|GAO|LK|RP|PAD|WAN|PWD|PMP|PBR|VN|PPC|NK|K|AH|I|JP|JU|UDZ|CHM|DDN|LN|CL|CLH|DKM|GK|WD|ED|DDK|DLN|DRN|DFD|GZB|DVV|GUR|GGN|ND|HHN|HAS|HYD|HKP|BWF|BBW|BKM|BSN|BL|BIN|ST|KN)-\\w*"

其中\b 代表单词边界,然后是一组代码替代项 ((?:...)),然后是连字符 (-),后跟零个或多个字母数字/下划线符号 (\w*)。

这是一个演示代码:

> consolidated_csv_v2 <- c("Head Office","(cancelled)","(cancelled)","(cancelled)","Deepali Mishra Ah-5564 Tst", "(cancelled)","SHRUTI BHAGAT AH-2445 AG","SUMIT SETHI AH-5747 AG","SUJATA VORA AH-5361 AG","Deepali Mishra Ah-5564 Tst")
> ccode<-c('S','PD','CH','ML','MD','VA','BVI','DB','KD','KE','PW','COL','AD','MET','VP','SI','VR','GAO','LK','RP','PAD','WAN','PWD','PMP','PBR','VN','PPC','NK','K','AH','I','JP','JU','UDZ','CHM','DDN','LN','CL','CLH','DKM','GK','WD','ED','DDK','DLN','DRN','DFD','GZB','DVV','GUR','GGN','ND','HHN','HAS','HYD','HKP','BWF','BBW','BKM','BSN','BL','BIN','ST','KN')
> reg <- paste0("\\b(?:", paste(ccode, collapse="|"),")-\\w*")
> str_extract(consolidated_csv_v2, reg)
 [1] NA        NA        NA        NA        NA        NA        "AH-2445"
 [8] "AH-5747" "AH-5361" NA       
> 

更新

并非所有单词都后跟“-”,有些单词后跟一个空格,有些单词之间没有任何字符。

这个要求是相当普遍的,但我们可以在一组交替之后使用惰性点匹配 (.*?) 来满足它,以匹配除换行符之外的任何 0+ 字符,直到第一组为止后跟单词边界 (\b) 的数字 (\d+)。使用

reg <- paste0("(?i)\\b(?:", paste(ccode, collapse="|"),").*?\\d+\\b")

regex demo

要使此模式不区分大小写,只需在第一个 \b 前面添加一个 (?i)

【讨论】:

  • 非常感谢。并非所有单词都后跟'-',有些单词后跟一个空格,有些单词之间没有任何字符。但都以数字结尾。如果您也可以为此提供解决方案,那将很有帮助。并且,关于如何处理“S”等单个字符的任何帮助。
  • 试试reg &lt;- paste0("\\b(?:", paste(ccode, collapse="|"),").*?\\d+\\b")
  • 我不太喜欢.*?,但是你的有些后面是空格,有些中间没有任何字符听起来不太准确。请检查实际要求并更新问题,以便我们为您提供最安全的模式。
  • 再次感谢您的努力。我已经更新了符合我所有要求的测试集。
  • 完成!非常感谢!这是区分大小写的。如何让它不区分大小写?
【解决方案2】:

我们可以试试

pat <- paste0("(?i)\\b(", paste(ccode, collapse="|"),")-.*")
str_extract(v1, pat)
#[1] NA            NA            NA            NA            "Ah-5564 Tst" NA            "AH-2445 AG"  "AH-5747 AG"  "AH-5361 AG"  "Ah-5564 Tst"

数据

v1 <- c("Head Office", "(cancelled)", "(cancelled)", "(cancelled)", 
"Deepali Mishra Ah-5564 Tst", "(cancelled)", "SHRUTI BHAGAT AH-2445 AG", 
"SUMIT SETHI AH-5747 AG", "SUJATA VORA AH-5361 AG", "Deepali Mishra Ah-5564 Tst")

【讨论】:

  • 感谢您的帮助!
猜你喜欢
  • 1970-01-01
  • 2012-03-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-02
  • 1970-01-01
相关资源
最近更新 更多