Note: sub1() and sub2() are both from “real” R code in getPackageName() [before 2015-06-25] (MM: ~/R/D/r-devel/R/src/library/methods/R/packageName.R )

### Function definitions :
###
sub0  <- function(pkg) sub( "package:", "",  pkg, fixed = TRUE)
sub0r <- function(pkg) sub("^package:", "", pkg)
##  ^ "r" := [r]egexp = regular expression

sub1 <- function(pkg) {
    if(regexpr("package:", pkg, fixed = TRUE) == 1L)
        sub("package:","", pkg, fixed = TRUE)
    else pkg
}

sub2a <- function(pkg) {
    if(identical(substr(pkg, 1L, 8L), "package:"))
    substr(pkg, 9L, 1000000L)# <- as in substring()
    else pkg
}
sub2b <- function(pkg) {
    if(identical(substr(pkg, 1L, 8L), "package:"))
    substring(pkg, 9L)
    else pkg
}

sub2 <- function(pkg) {
    if(identical(substr(pkg, 1L, 8L), "package:"))
    substr(pkg, 9L, nchar(pkg, "c"))
    else pkg
}


require(microbenchmark)
## Loading required package: microbenchmark
options(digits=4)

en <- "package:stats"
(mb <- microbenchmark(sub0(en), sub1(en), sub2a(en), sub2b(en), sub2(en), sub0r(en),
                      times=1000))
## Unit: microseconds
##       expr   min    lq  mean median    uq   max neval   cld
##   sub0(en) 1.504 1.891 2.276  2.115 2.352 22.55  1000 a    
##   sub1(en) 3.236 3.987 4.692  4.358 4.762 17.32  1000   c  
##  sub2a(en) 2.670 3.377 4.107  3.721 4.077 32.11  1000  b   
##  sub2b(en) 3.374 4.236 5.021  4.614 5.031 40.69  1000    d 
##   sub2(en) 3.557 4.424 5.192  4.795 5.200 26.73  1000    d 
##  sub0r(en) 7.840 8.620 9.334  8.926 9.409 30.64  1000     e

R-devel 2015-06-25 is a bit faster on same platform [lynne, Linux F 20] :

## Unit: microseconds
##      expr   min    lq  mean median    uq   max neval   cld
##  sub0(en) 1.392 1.800 2.052  1.977 2.202 11.66  1000 a
##  sub1(en) 3.014 3.886 4.315  4.236 4.571 18.40  1000   c
## sub2a(en) 2.482 3.183 3.513  3.449 3.729 16.09  1000  b
## sub2b(en) 3.090 3.984 4.374  4.340 4.646 16.18  1000   c
##  sub2(en) 3.353 4.382 4.853  4.755 5.103 15.99  1000    d
## sub0r(en) 7.323 8.047 8.636  8.360 8.753 28.96  1000     e
plot(mb, log="y", notch=TRUE) ## clearly '1' is better than '2' but there's more!

m12 <- summary(mb)[,"median"]; round(m12 / m12[1], 3)
## [1] 1.000 2.061 1.760 2.182 2.268 4.221
## 1.000 2.100 2.405 4.205   [R-devel 2015-06-25, "lynne"]

This does not work as the if(.) version above would need to be vectorized :

if(FALSE) {
 e4 <- paste0("package:", c("base", "stats", "utils", "tools"))
 (m4 <- microbenchmark(sub0(e4), sub1(e4), sub2(e4), sub2a(e4), sub0r(e4), times=1000))
}

and so, sub0r (“^pattern:”) is “safer” – but much slower and and not needed for package-name mangling