答案是gregexpr 返回一个数字向量列表。您自己的示例可能有点误导,因为 gregexpr 可以将 vector 字符串作为其第二个参数,而不仅仅是单个字符串。因此,它需要在提供的字符向量中为 each 字符串返回一个数字向量,以表示 each 字符串中匹配的起点。它将所有这些向量一起存储在一个列表中。
那么为什么结果看起来不像一个正常的数字向量列表(就像您使用list(1:5, 6:10) 得到的那样)?这是因为gregexpr 返回的列表中的每个向量也都具有三个属性。
属性在 R 中非常有用。它们是一种存储与变量相关的补充信息的方式,不会改变其其他行为。
我们可以这样设置属性:
x <- 1
attr(x, "Number") <- TRUE
所以当我们查看 x 时,我们得到:
x
#> [1] 1
#> attr(,"Number")
#> [1] TRUE
我们可以通过调用attr来访问属性:
attr(x, "Number")
#> [1] TRUE
但我们仍然可以将x 用作数字变量,就好像它没有这个属性一样:
x + 2
#> [1] 3
#> attr(,"Number")
#> [1] TRUE
将此与您可能尝试将有用属性存储在命名列表中的替代方式进行比较:
x <- list(1, Number = TRUE)
这包含我们想要的信息,但我们失去了功能:
x + 2
#> Error in x + 2: non-numeric argument to binary operator
关于gregexpr,它需要返回一个列表,因为它是矢量化的。看:
gregexpr("abab",c("abababab", "zzababzz"))
#> [[1]]
#> [1] 1 5
#> attr(,"match.length")
#> [1] 4 4
#> attr(,"index.type")
#> [1] "chars"
#> attr(,"useBytes")
#> [1] TRUE
#>
#> [[2]]
#> [1] 3
#> attr(,"match.length")
#> [1] 4
#> attr(,"index.type")
#> [1] "chars"
#> attr(,"useBytes")
#> [1] TRUE
我们已经传递了多个字符串,所以我们需要一个包含多个结果的列表,每个字符串对应一个结果。每个列表元素都会报告匹配的位置,但它也会告诉您命名属性中匹配的长度。这实际上是一种非常巧妙的方式来存储您可能需要的有关正则表达式匹配的所有信息。
例如,假设我有一堆字符串:
my_strings <- c("A1234", "35467 65432", "13456765")
我想知道每个字符串中连续数字的最大数量。然后我可以这样做:
result <- gregexpr("\\d+", my_strings)
sapply(result, function(y) max(attr(y, "match.length")))
#> [1] 4 5 8