如何计算非结构化数据中第三列之前的字符数(包括空格)?
How to count number of characters(including spaces) before the third column in unstructured data?
我有如下所示的非结构化数据:
x <- c("24-March-2017 text1 874874455221112 Text text text10",
"25-March-2017 text2 54654656TEXT Text text 11",
"24-March-2017 text3 874874455221112 Text text text 12")
我想计算第 3 列之前的字符数,包括空格。例如,在第一行中,我想计算数字 874874455221112 之前的所有内容。
使用 stringr
库:
library(stringr)
str_length(str_extract(x,"^(\S+\s+){2}"))
gregexpr
是基本的 R 正则表达式函数,returns 关于字符串中多个匹配项的位置的信息。要提取它们,您可以使用 regmatches
,但由于 gregexpr
returns 是每个匹配项的第一个字符的索引,您可以简单地搜索非 space 字符组\S+
、select第三个索引,减一得到前面字符的个数:
sapply(gregexpr('\S+', x), `[`, 3) - 1
#> [1] 30 34 31
这里有一些在 R 的基础上全部使用 regexpr
的单行代码。没有使用包。
1) 通常,您可以做出的假设越多,答案就越短。
在这里,我们假设当您在问题中写下您所指的文本时,我们会得到一个相当简洁的答案。字。在这种情况下,第三个字段是第一个以数字开头并以 space 开头的字段,因此寻找白色 space 字符 ("\s"
) 后跟数字 ("\d"
).
regexpr("\s\d", x)
给予:
[1] 30 34 31
attr(,"match.length")
[1] 2 2 2
attr(,"useBytes")
[1] TRUE
2) 如果单词假设不是这种情况,那么第二个字段可以以数字开头,那么我们可以很容易地通过更改第一个字符将其简化为上述情况第二个字段的非数字,x
说,然后执行上述操作。在下面的代码中,"\S"
匹配任何非白色 space 字符。这给出了与 (1) 相同的答案,除了它在第二个字段以数字开头的情况下也有效。
regexpr("\s\d", sub("\s\S", " x", x))
3) 另一种方法是匹配前两个字段和它们之后的space。 regexpr
将 return "match.length"
属性中所需的字符长度。
attr(regexpr("^(\S+\s+){2}", x), "match.length")
## [1] 30 34 31
注意:如果问题是阅读4个字段的部分答案,那么可以直接通过在字段之间插入逗号或其他特殊字符然后读取结果来完成使用 read.table
。我假设第 3 个字段都是数字,所以 TEXT 应该在第 4 个字段中,但如果它应该在第 3 个字段中,则将 "\d"
替换为 "\S"
in pat
.
pat <- "^(\S+)\s+(\S+)\s+(\d+)\s*(.*)"
read.table(text = sub(pat, "\1,\2,\3,\4", x), sep = ",", colClasses = "character")
给予:
V1 V2 V3 V4
1 24-March-2017 text1 874874455221112 Text text text10
2 25-March-2017 text2 54654656 TEXT Text text 11
3 24-March-2017 text3 874874455221112 Text text text 12
我有如下所示的非结构化数据:
x <- c("24-March-2017 text1 874874455221112 Text text text10",
"25-March-2017 text2 54654656TEXT Text text 11",
"24-March-2017 text3 874874455221112 Text text text 12")
我想计算第 3 列之前的字符数,包括空格。例如,在第一行中,我想计算数字 874874455221112 之前的所有内容。
使用 stringr
库:
library(stringr)
str_length(str_extract(x,"^(\S+\s+){2}"))
gregexpr
是基本的 R 正则表达式函数,returns 关于字符串中多个匹配项的位置的信息。要提取它们,您可以使用 regmatches
,但由于 gregexpr
returns 是每个匹配项的第一个字符的索引,您可以简单地搜索非 space 字符组\S+
、select第三个索引,减一得到前面字符的个数:
sapply(gregexpr('\S+', x), `[`, 3) - 1
#> [1] 30 34 31
这里有一些在 R 的基础上全部使用 regexpr
的单行代码。没有使用包。
1) 通常,您可以做出的假设越多,答案就越短。
在这里,我们假设当您在问题中写下您所指的文本时,我们会得到一个相当简洁的答案。字。在这种情况下,第三个字段是第一个以数字开头并以 space 开头的字段,因此寻找白色 space 字符 ("\s"
) 后跟数字 ("\d"
).
regexpr("\s\d", x)
给予:
[1] 30 34 31
attr(,"match.length")
[1] 2 2 2
attr(,"useBytes")
[1] TRUE
2) 如果单词假设不是这种情况,那么第二个字段可以以数字开头,那么我们可以很容易地通过更改第一个字符将其简化为上述情况第二个字段的非数字,x
说,然后执行上述操作。在下面的代码中,"\S"
匹配任何非白色 space 字符。这给出了与 (1) 相同的答案,除了它在第二个字段以数字开头的情况下也有效。
regexpr("\s\d", sub("\s\S", " x", x))
3) 另一种方法是匹配前两个字段和它们之后的space。 regexpr
将 return "match.length"
属性中所需的字符长度。
attr(regexpr("^(\S+\s+){2}", x), "match.length")
## [1] 30 34 31
注意:如果问题是阅读4个字段的部分答案,那么可以直接通过在字段之间插入逗号或其他特殊字符然后读取结果来完成使用 read.table
。我假设第 3 个字段都是数字,所以 TEXT 应该在第 4 个字段中,但如果它应该在第 3 个字段中,则将 "\d"
替换为 "\S"
in pat
.
pat <- "^(\S+)\s+(\S+)\s+(\d+)\s*(.*)"
read.table(text = sub(pat, "\1,\2,\3,\4", x), sep = ",", colClasses = "character")
给予:
V1 V2 V3 V4
1 24-March-2017 text1 874874455221112 Text text text10
2 25-March-2017 text2 54654656 TEXT Text text 11
3 24-March-2017 text3 874874455221112 Text text text 12