【问题标题】:Modify the replacement value of a regex match in R修改 R 中正则表达式匹配的替换值
【发布时间】:2020-01-29 21:49:48
【问题描述】:

我一直在使用 R 处理 PDF,并且数据以多种格式呈现。我想将数据转换为最终数据框;现在是chr 格式。将其放入数据框中的最简单方法是在空白处拆分然后上传。所有数据如下所示;长字符串中的 611 项。

2019-02-05 1-02/05/2019-123456-A  Thorton, Billy Bob         W123455834   XXX-XX-1776 ALEXANDER      HAMILTON
2019-02-08 1-02/08/2019-876543-B  Dern, Laura         P98765432   XXX-XX-1789 BETSY      ROSS

上述格式的数据存在一些问题:

  1. Billy Bob 之间的空间将导致在 数据;我们只有一个名称字段。加入这些后,我们可以轻松删除逗号。
  2. 拆分之间存在不同程度的空白。
  3. 其他代码是字母数字。

在这篇文章中,我将向您展示一些正则表达式代码和提示,例如分组、更改大小写以及使用 Perl 扩展模式回顾特定组:

  1. 用比利鲍勃创造一个名字
  2. 仅将名称转换为小写,以便以后处理。如果我们想要全部小写,那么只需使用 tolower() 函数。

解决方案基于这篇文章,我正在扩展它以使其更通用: gsub error turning upper to lower case in R

【问题讨论】:

  • 看着这个我怀疑分隔符是制表符。尝试阅读sep="\t"
  • 不是,数量不同,我马上就试了。
  • 另一个想法是使用 pdftools-pkg: Package: pdftools\n Type: Package\n Title: Text Extraction, Rendering and Converting of PDF Documents\n Version: 2.3

标签: r regex replace


【解决方案1】:

第一步是将所有出现的两个名字(Billy Bob、Jimmie Sue 等)连接到一个名字中,这样我们就可以得到Thorton,BillyBob,然后我们可以在空格处进行拆分。

我们正在寻找的模式是lowercase space Uppercase。正则表达式如下:

pattern = stringr::regex("([a-z])( )([A-Z][a-z])")
data_join = gsub(pattern=pattern, replacement='\\1\\3', x=data, perl=TRUE)

我们在正则表达式中使用() 进行三个分组:一个用于匹配的每个元素。 当使用gsub() 时,通过指定replace='\\1\\3',我们告诉正则表达式回顾并使用正则表达式的第一个和第三个元素作为替换,并跳过第二个元素,这是进行连接的空间。

要使所有名称都小写,我们需要排除字母数字中的字母以及“XXX”模式。

pattern_low = stringr::regex("(([A-z]){2,}[^XXX-XX-])")
data_low = gsub(pattern=pattern_low, perl = T, replacement ='\\L\\1', x=data_join)

解析正则表达式:([A-z]){2,} 部分查找至少两个字母以处理字母数字问题。 [^XXX-XX-] 告诉它排除Xs 的那些实例。此外,我们在其周围添加了一组额外的 () 以使其成为一个组。

在替换中,我们使用\\L 指定更低,\\1 使其适用于整个组。我在第一种情况下尝试了多个分组,但效果不佳。

现在我们可以将其拆分并加载到数据框中:

# put it in a data frame
df_all = data_low %>% strsplit(split = "\\s+")

添加+ 允许它处理不同的空白。

【讨论】:

    【解决方案2】:

    在最后的注释中使用Lines,将其读入L,将重复的空格替换为单个空格,然后将strcapture与指示的模式一起使用。请注意,\d 匹配数字,\D 匹配非数字,\S 匹配非空白字符。没有使用任何包。

    L <- readLines(textConnection(Lines))
    L <- gsub("  +", " ", L)
    
    pat <- "^(\\S+) (\\S+) (.*) (\\D\\d+) (\\S+) (\\S.*)$"
    strcapture(pat, L, proto = list(date = character(0), 
      key = character(0), name1 = character(0), driver = character(0), 
      code = character(0), name2 = character(0)))
    

    给予:

            date                   key              name1     driver        code
    1 2019-02-05 1-02/05/2019-123456-A Thorton, Billy Bob W123455834 XXX-XX-1776
    2 2019-02-08 1-02/08/2019-876543-B        Dern, Laura  P98765432 XXX-XX-1789
                   name2
    1 ALEXANDER HAMILTON
    2         BETSY ROSS
    

    注意

    Lines <- "2019-02-05 1-02/05/2019-123456-A  Thorton, Billy Bob         W123455834   XXX-XX-1776 ALEXANDER      HAMILTON
    2019-02-08 1-02/08/2019-876543-B  Dern, Laura         P98765432   XXX-XX-1789 BETSY      ROSS"
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-25
      • 2012-05-16
      • 1970-01-01
      • 1970-01-01
      • 2013-12-06
      • 2021-04-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多