2

我需要找到最好的方法来匹配来自 CSV 或文本文件的符号、字母和数字的精确模式组合与非常非结构化的数据集。

我需要准确地提取模式“<code>BR1*********”(BR1+ 正好 9 位),它位于行 :61: 的中间​​以及模式“<code>?54** *”(?54+ 正好 3 位数字),它始终位于行 :61: 的末尾。

两种模式都是重复的,但数字组合不同。

我已经尝试过grepgrepl但到目前为止没有成功。结果,我总是收到整行,其中该模式近似匹配,但符号和数字不完全匹配。

以下是数据集的一小部分:

:11:hgttu6576575?//80&&80980jhkhkhlkhkh  gjdggfjsdf?kjhkuhsfk778798978**&
:27:jhkjhuiy867tjhfsh/.>?kjklh8ggdhkotrdkhofkhodkgj
:61:kjljlkfjsdlBR1678899458iyuyugug7787?>?///uhhiuyi
jhkhkjhiy878697y8hukjlu97 ??///khiuy8oujhuhijk?54160
:11:hgggdgf79878yiuhlkhkh  gjdggfhuihiuhuiou89 ioiojsdf?kjhkuhsfk778798978**&
:27:jhkjhuiy867tjhfsh/.>?kjklh8ggdhkotrdkhofkhodkgj
:61:kjljlkfjsdlBR1234885765iyuyugug7787?>?///uhhiuyi
jhkhkjhiy878697y8hukjlu97 ??///khiuy8oujhuhijk?54190
4

5 回答 5

3

strapplycgsubfn 包中的可用于提取这些部分。在这里,我们提取整个字符串,或者如果您只想要数字部分在数字部分周围放置括号,例如pat1 <- "BR(1\\d{9})"

library(gsubfn)

pat1 <- "BR1\\d{9}"
pat2 <- "[?]54\\d{3}$"

strapplyc(lines, pat1, simplify = c)
## [1] "BR1678899458" "BR1234885765"

strapplyc(lines, pat2, simplify = c)
## [1] "?54160" "?54190"

或两者兼而有之:

strapplyc(lines, paste(pat1, pat2, sep = "|"), simplify = c)
## [1] "BR1678899458" "?54160"       "BR1234885765" "?54190"  

grep如果您想要行号(即第一行是 1,第二行是 2,等等)而不是值本身,请使用相同的模式。

补充如果只有几千行,读取文件应该没有问题:

lines <- readLines("File.txt")

如果它真的太大,你可以在 sqldf 包中读取 use ,它在一行代码中可以读取 setup 一个 sqlite 数据库将文件读入其中,然后将一部分行提取到 R中read.csv.sql。这里我们假设没有?文件,但如果使用文件中没有的其他分隔符:

library(sqldf)

lines <- read.csv.sql("File.txt", header = FALSE, sep = "?", 
      sql = "select * from file where V1 like '%BR1%' or V1 like '%54%'")
# now use strapplyc as above
于 2014-10-25T15:27:22.083 回答
2

您可以使用基础 R 处理这些匹配项的提取。

> unlist(regmatches(lines, gregexpr('BR1\\d{9}|\\?54\\d{3}', lines)))
# [1] "BR1678899458" "?54160"       "BR1234885765" "?54190" 
于 2014-10-25T15:40:59.727 回答
2

我对自然语言描述的阅读是只有 2 行满足要求。例如,第 4 行确实有一个 "?54nnn$" 模式,但该行不以 ":61:" 开头:

dat=readLines(textConnection(":11:hgttu6576575?//80&&80980jhkhkhlkhkh  gjdggfjsdf?kjhkuhsfk778798978**&
:27:jhkjhuiy867tjhfsh/.>?kjklh8ggdhkotrdkhofkhodkgj
:61:kjljlkfjsdlBR1678899458iyuyugug7787?>?///uhhiuyi
jhkhkjhiy878697y8hukjlu97 ??///khiuy8oujhuhijk?54160
:11:hgggdgf79878yiuhlkhkh  gjdggfhuihiuhuiou89 ioiojsdf?kjhkuhsfk778798978**&
:27:jhkjhuiy867tjhfsh/.>?kjklh8ggdhkotrdkhofkhodkgj
:61:kjljlkfjsdlBR1234885765iyuyugug7787?>?///uhhiuyi
jhkhkjhiy878697y8hukjlu97 ??///khiuy8oujhuhijk?54190"))

> grep("^:61:.+(BR1\\d{9}|[?]54\\d{3}$)", dat)
#[1] 3 7

修改测试用例以查看我的模式建议对于我认为的问题是否正确执行:

> dat=readLines(textConnection(":11:hgttu6576575?//80&&80980jhkhkhlkhkh  gjdggfjsdf?kjhkuhsfk778798978**&
+ :27:jhkjhuiy867tjhfsh/.>?kjklh8ggdhkotrdkhofkhodkgj
+ :61:kjljlkfjsdlBR1678899458iyuyugug7787?>?///uhhiuyi
+ :61:jhkhkjhiy878697y8hukjlu97 ??///khiuy8oujhuhijk?54160
+ :11:hgggdgf79878yiuhlkhkh  gjdggfhuihiuhuiou89 ioiojsdf?kjhkuhsfk778798978**&
+ :27:jhkjhuiy867tjhfsh/.>?kjklh8ggdhkotrdkhofkhodkgj
+ :61:kjljlkfjsdlBR1234885765iyuyugug7787?>?///uhhiuyi
+ jhkhkjhiy878697y8hukjlu97 ??///khiuy8oujhuhijk?54190")
+ )
> grep("^:61:.+(BR1\\d{9}|[?]54\\d{3}$)", dat)
[1] 3 4 7
于 2014-10-25T15:31:19.490 回答
2

尝试

   library(stringr)
   unlist(str_extract_all(lines, "(BR1\\d{9})|(\\?54\\d{3})"))
   #[1] "BR1678899458" "?54160"        "BR1234885765" "?54190"   

更新

如果它是一个大文件,你可以使用stringi,这会更快

  library(stringi)
  na.omit(unlist(stri_extract_all_regex(lines, "(BR1\\d{9})|(\\?54\\d{3})")))
  #[1] "BR1678899458" "?54160"       "BR1234885765" "?54190"     

数据

lines <- readLines(textConnection(':11:hgttu6576575?//80&&80980jhkhkhlkhkh  gjdggfjsdf?kjhkuhsfk778798978**&
 :27:jhkjhuiy867tjhfsh/.>?kjklh8ggdhkotrdkhofkhodkgj
 :61:kjljlkfjsdlBR1678899458iyuyugug7787?>?///uhhiuyi jhkhkjhiy878697y8hukjlu97 ??///khiuy8oujhuhijk?54160
 :11:hgggdgf79878yiuhlkhkh  gjdggfhuihiuhuiou89 ioiojsdf?kjhkuhsfk778798978**&
 :27:jhkjhuiy867tjhfsh/.>?kjklh8ggdhkotrdkhofkhodkgj
 :61:kjljlkfjsdlBR1234885765iyuyugug7787?>?///uhhiuyi jhkhkjhiy878697y8hukjlu97 ??///khiuy8oujhuhijk?54190'))
于 2014-10-25T15:16:44.990 回答
2
dat <- readLines(textConnection(":11:hgttu6576575?//80&&80980jhkhkhlkhkh  gjdggfjsdf?kjhkuhsfk778798978**&
:27:jhkjhuiy867tjhfsh/.>?kjklh8ggdhkotrdkhofkhodkgj
:61:kjljlkfjsdlBR1678899458iyuyugug7787?>?///uhhiuyi
jhkhkjhiy878697y8hukjlu97 ??///khiuy8oujhuhijk?54160
:11:hgggdgf79878yiuhlkhkh  gjdggfhuihiuhuiou89 ioiojsdf?kjhkuhsfk778798978**&
:27:jhkjhuiy867tjhfsh/.>?kjklh8ggdhkotrdkhofkhodkgj
:61:kjljlkfjsdlBR1234885765iyuyugug7787?>?///uhhiuyi
jhkhkjhiy878697y8hukjlu97 ??///khiuy8oujhuhijk?54190"))

library(stringr)

unlist(str_match_all(dat, "(BR1[[:digit:]]{9})|(\\?54[[:digit:]]{3})"))
##  [1] "BR1678899458" "BR1678899458" ""             "?54160"      
##  [5] ""             "?54160"       "BR1234885765" "BR1234885765"
##  [9] ""             "?54190"       ""             "?54190"

如果我们对您需要的格式有更多了解,我们可以为您提供更好的帮助。

于 2014-10-25T15:26:58.110 回答