该序列将类似于:
"4122222222222281222222211111212"
Run Code Online (Sandbox Code Playgroud)
我想要的结果是:
"1222222222222"
"12222222"
"12"
"12"
Run Code Online (Sandbox Code Playgroud)
您可以看到该模式中可以有任意数量的“2”。
有没有办法在R中找到这样的模式?
关键是要使用模式 "12+"。
\n\n人物
\n+表示“匹配前面的字符一次或多次”
您可以stringr使用以下str_extract_all()函数在库中执行此操作:
x <- "4122222222222281222222211111212"\nstringr::str_extract_all(x, "12+")\n# [[1]]\n# [1] "1222222222222" "12222222" "12" "12" \nRun Code Online (Sandbox Code Playgroud)\n或者在基本 R 中您可以使用regmatches():
m <- gregexpr("12+", x)\nregmatches(x, m)\n# [[1]]\n# [1] "1222222222222" "12222222" "12" "12" \nRun Code Online (Sandbox Code Playgroud)\n这两种方法都是矢量化的并返回一个列表。这很有用,就像x数据框列一样,输出将是 的列表length(x),其中每个元素都是包含所有匹配项的字符向量。但是,如果x是一个长度为 的向量1,您可能希望将结果包装起来unlist()以返回一个向量。通过该stringr方法,您还可以执行以下操作:
stringr::str_extract_all(x, "12+", simplify = TRUE) \n# [,1] [,2] [,3] [,4]\n# [1,] "1222222222222" "12222222" "12" "12"\nRun Code Online (Sandbox Code Playgroud)\n这将返回一个字符矩阵,在本例中只有一行。但是,如果您的输入具有 length ,这可能不是所需的结果> 1,因为不同数量的匹配将导致包含""条目(而不是NA)的字符数组:
x <- c("4122222222222281222222211111212", "135", "123")\nstringr::str_extract_all(x, "12+", simplify = TRUE) \n# [,1] [,2] [,3] [,4]\n# [1,] "1222222222222" "12222222" "12" "12"\n# [2,] "" "" "" "" \n# [3,] "12" "" "" "" \nRun Code Online (Sandbox Code Playgroud)\n有关stringr函数和正则表达式匹配字符的更多信息,请参阅 RStudio 的有用stringr 备忘单。
您还可以使用stri_extract_all_regex(x, "12+"),它stringr::str_extract_all()是一个包装器。
stringr比 快得多regmatches()。有一些历史 基准表明它stringi比stringr. 然而,由于v1.0.0of stringr,它的许多函数都是函数的包装器stringi,两个包之间的性能没有太大差异。以下是该正则表达式的结果,向量范围从长度1到1e6行:
stringi对于非常短的向量,似乎稍快一些,但实际时间差很小(纳秒)。对于较长的向量,我们看不到太大的相对差异。有趣的是,即使数据很大,简化为矩阵的性能成本相对于创建正则表达式的成本来说并不是很高。
library(stringr)\nlibrary(stringi)\n\nresults <- bench::press(\n n_strings = 10^(0:6),\n pattern = "12+",\n {\n x <- stri_rand_strings(n = n_strings, length = 20, pattern = "[1-5]")\n bench::mark(\n min_iterations = 10,\n check = FALSE,\n str_extract_all = {\n str_extract_all(x, pattern)\n },\n str_extract_all_simplify = {\n str_extract_all(x, pattern, simplify = TRUE)\n },\n stringi = {\n stri_extract_all_regex(x, pattern)\n },\n base = {\n regmatches(x, gregexpr(pattern, x))\n }\n )\n }\n)\n\n# # A tibble: 28 \xc3\x97 11\n# expression n_strings pattern min median `itr/sec` mem_alloc `gc/sec` n_itr n_gc total_time\n# <bch:expr> <dbl> <chr> <bch:tm> <bch:tm> <dbl> <bch:byt> <dbl> <int> <dbl> <bch:tm>\n# 1 str_extract_all 1 12+ 20.4\xc2\xb5s 22.5\xc2\xb5s 36001. 264B 3.60 9999 1 277.74ms\n# 2 str_extract_all_simplify 1 12+ 21.5\xc2\xb5s 22.7\xc2\xb5s 36481. 264B 3.65 9999 1 274.09ms\n# 3 stringi 1 12+ 6.3\xc2\xb5s 6.6\xc2\xb5s 125851. 0B 0 10000 0 79.46ms\n# 4 base 1 12+ 24.3\xc2\xb5s 27.2\xc2\xb5s 28786. 8.09KB 5.76 9998 2 347.32ms\n# 5 str_extract_all 10 12+ 25\xc2\xb5s 28.8\xc2\xb5s 22913. 264B 2.29 9999 1 436.4ms\n# 6 str_extract_all_simplify 10 12+ 26.4\xc2\xb5s 27.9\xc2\xb5s 30625. 472B 3.06 9999 1 326.49ms\n# 7 stringi 10 12+ 10.4\xc2\xb5s 10.8\xc2\xb5s 72548. 0B 7.26 9999 1 137.83ms\n# 8 base 10 12+ 72.4\xc2\xb5s 84.1\xc2\xb5s 8692. 80.94KB 8.72 3988 4 458.8ms\n# 9 str_extract_all 100 12+ 64.6\xc2\xb5s 68.7\xc2\xb5s 12231. 1.09KB 2.03 6039 1 493.75ms\n# 10 str_extract_all_simplify 100 12+ 69.8\xc2\xb5s 75.55\xc2\xb5s 10732. 3.48KB 2.02 5300 1 493.87ms\n# 11 stringi 100 12+ 49.7\xc2\xb5s 51.8\xc2\xb5s 16697. 848B 0 8335 0 499.18ms\n# 12 base 100 12+ 507.7\xc2\xb5s 677.15\xc2\xb5s 1201. 813.95KB 13.2 548 6 456.18ms\n# 13 str_extract_all 1000 12+ 487.4\xc2\xb5s 546.45\xc2\xb5s 1526. 8.12KB 2.02 756 1 495.26ms\n# 14 str_extract_all_simplify 1000 12+ 538.8\xc2\xb5s 568.5\xc2\xb5s 1610. 47.23KB 0 805 0 500.08ms\n# 15 stringi 1000 12+ 469.1\xc2\xb5s 558.1\xc2\xb5s 1555. 7.86KB 2.01 772 1 496.62ms\n# 16 base 1000 12+ 5.01ms 5.56ms 177. 7.95MB 20.2 70 8 395.96ms\n# 17 str_extract_all 10000 12+ 4.94ms 5.32ms 170. 78.43KB 0 85 0 500.24ms\n# 18 str_extract_all_simplify 10000 12+ 5.24ms 5.8ms 167. 390.98KB 1.98 84 1 503.92ms\n# 19 stringi 10000 12+ 4.86ms 5.34ms 160. 78.17KB 2.00 80 1 500.44ms\n# 20 base 10000 12+ 78.43ms 88.56ms 11.0 79.46MB 12.1 10 11 905.52ms\n# 21 str_extract_all 100000 12+ 53.45ms 57.39ms 16.8 781.55KB 1.68 10 1 595.49ms\n# 22 str_extract_all_simplify 100000 12+ 59.91ms 66.8ms 13.6 4.58MB 1.36 10 1 734.33ms\n# 23 stringi 100000 12+ 52.52ms 53.85ms 18.3 781.3KB 0 10 0 545.4ms\n# 24 base 100000 12+ 808.5ms 992.12ms 0.956 794.6MB 14.6 10 153 10.46s\n# 25 str_extract_all 1000000 12+ 533.78ms 627.43ms 1.16 7.63MB 0.116 10 1 8.6s\n# 26 str_extract_all_simplify 1000000 12+ 637.49ms 709.24ms 1.36 53.41MB 0.136 10 1 7.34s\n# 27 stringi 1000000 12+ 537.19ms 600.58ms 1.64 7.63MB 0.164 10 1 6.09s\n# 28 base 1000000 12+ 10s 11.74s 0.0857 7.76GB 3.03 10 353 1.95m\n\n\n# Plot\nlibrary(ggplot2)\np <- autoplot(results) +\n theme_bw() +\n facet_wrap(vars(n_strings), ncol = 1, labeller = "label_both")\nRun Code Online (Sandbox Code Playgroud)\n