【问题标题】:Regular Expressions and substring in RR中的正则表达式和子字符串
【发布时间】:2020-04-08 19:35:41
【问题描述】:

我正在尝试清理数据并将其更改为特定格式。

所有数据应具有以下格式:2 位数字、3 个字母 (MKT)、4 位数字、1 个下划线和 1 位数字(例如 66MKT1234_1)

假设我有以下数据:

V <- c("66MKT030_2", "66MGT1220_2", "66MGT063_1", "66MKT350_2","22233366698","66MKT3500_2", "9999999")

要更正的内容: a) 向量的第 1、第 3 和第 4 个元素在 3 个字母 (MTG) 之后只有 3 个数字。在这种情况下,我需要在最后一个字母后添加一个 0 数字 b) 第 2 和第 3 个元素需要从“MGT”到“MTG”正确 c) 需要删除第 5 和第 7 个元素。

我的方法是:

第 1 步 - 删除与格式不匹配的数据(2 个数字,3 个字母 (MKT),4 个数字,1 个下划线和 1 个数字)

aa <- grepl("\\d{2}\\w{3}\\d{3,4}[:punct:]\\d{1}", V)
V2 <- V[aa]

第 2 步 - 使用 gsub 将“MGT”更正为“MTG”

第 3 步 - 如果数字长度为 3,则想办法在字母后添加数字 0(例如,第一个元素应从 66MKT030_2 更改为 66MKT0030_2)

我被困在第 1 步,因为我的代码无法从向量中清除第 5 个(“22233366698”)和第 7 个(“9999999”)元素。

你能帮我看看如何以一种更好的方式做到这一点吗?

谢谢

【问题讨论】:

  • 这听起来你可能有一个相当大的清理工作。您可能只想将问题集中在您描述的步骤之一上。
  • 试试sub("^(\\d{2}[[:alpha:]]{3})(\\d{3}\\D)", "\\10\\2", sub("MGT", "MTG", grep("^\\d+$", V, value=TRUE, invert=TRUE), fixed=TRUE))
  • 谢谢维克托。它似乎工作。你能解释一下 "\\10\\2" & grep("^\\d+$", V, value=TRUE, invert=TRUE 是做什么的吗?

标签: r regex substring


【解决方案1】:

你可以使用

sub("^(\\d{2}[[:alpha:]]{3})(\\d{3}\\D)", "\\10\\2", sub("MGT", "MTG", grep("^\\d+$", V, value=TRUE, invert=TRUE), fixed=TRUE))

在单独的步骤中:

V <- grep("^\\d+$", V, value=TRUE, invert=TRUE)
V <- sub("MGT", "MTG", V, fixed=TRUE)
sub("^(\\d{2}[[:alpha:]]{3})(\\d{3}\\D)", "\\10\\2", V)

输出:

[1] "66MKT0030_2" "66MTG1220_2" "66MTG0063_1" "66MKT0350_2" "66MKT3500_2"

详情

  • grep("^\\d+$", V, value=TRUE, invert=TRUE) - 过滤掉所有仅包含数字的项目(invert=TRUE 反转 ^\d+$ 正则表达式的结果)
  • sub("MGT", "MTG", V, fixed=TRUE) - 将 MGT 替换为 MTGfixed=TRUE 在不涉及正则表达式引擎的情况下对文字字符串进行此替换,这通常会加快处理速度)
  • sub("^(\\d{2}[[:alpha:]]{3})(\\d{3}\\D)", "\\10\\2", V) - 在仅由三位数字组成的第三个字段之前添加 0

第三步正则表达式详解:

  • ^ - 字符串开头
  • (\d{2}[[:alpha:]]{3}) - 第 1 组:两位数 (\d{2}),三个字母 ([[:alpha:]]{3})
  • (\d{3}\D) - 第 2 组:三个数字 (\d{3}) 和一个非数字 (\D)
  • \10\2 - 第 1 组,0,第 2 组值。

【讨论】:

  • 只是一个简单的问题。有没有办法返回向量中的哪些元素(即元素的索引/位置)被包含/排除在此步骤的原始向量中(V
  • 看来需要用grepl函数来完成。
  • @AnaAntunes grep("^\\d+$", V, invert=TRUE) 显示 1 2 3 4 6grep("^\\d+$", V) 显示 5 7value=TRUE 返回实际的字符向量,如果您删除参数,您将获得 ID。 grepl 返回布尔结果,不支持 invert 参数,但如果你有兴趣,你可以玩 grepl("^\\d+$", V)grepl("^(?!\\d+$)", V, perl=TRUE)
  • 感谢您的解释和帮助。现在我更好地理解了 grep
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-04-17
  • 2011-12-29
  • 1970-01-01
  • 1970-01-01
  • 2018-05-14
  • 2015-07-13
  • 1970-01-01
相关资源
最近更新 更多