stringr 1.6.0

  stringr

  Hadley Wickham

We’re delighted to announce the release of stringr 1.6.0! stringr provides a cohesive set of functions designed to make working with strings as easy as possible. You can install it from CRAN with:

install.packages("stringr")

This release includes some lifecycle changes, improvements to sql_like()/sql_ilike(), and a handful of other useful features. You can see a full list of changes in the release notes.

Lifecycle changes

This release includes two lifecycle changes that may affect existing code.

First, the ignore_case argument to str_like() is now deprecated. Previously, it defaulted to ignore_case = TRUE. This was a mistake because it doesn’t align with the conventions of the SQL LIKE operator, which is always case sensitive. Going forward, str_like() will always be case sensitive, so if you need case-insensitive matching, use the new str_ilike() function.

Second, if you use str_replace_all() with a function for the replacement argument, that function now receives all values in a single character vector instead of being called once for each individual string. This change dramatically improves performance, so I decided it was worth it despite its impact on existing code. It shouldn’t affect too much existing code in the wild, and it only broke 11 of the 2,381 CRAN packages that use stringr (which I fixed via PR). If you haven’t used this functionality before, it’s pretty cool, because it allows you to supply a function that can transform matches in any way you can imagine. For example, this code replaces color names with their corresponding hex values:

colours <- str_c("\\b", colors(), "\\b", collapse = "|")
col2hex <- function(col) {
  rgb <- col2rgb(col)
  rgb(rgb["red", ], rgb["green", ], rgb["blue", ], maxColorValue = 255)
}

# by Claude Code
poem <- "Azure skies meet honeydew light,
While coral blooms kiss morning's face.
Gold spills across the wheat-field bright,
As lavender shadows lose their place.
Turquoise waters catch the sun,
Where salmon leap through chartreuse streams.
Orchid petals, one by one,
Fall like plum-soft summer dreams.
"
cat(str_replace_all(poem, regex(colours, ignore_case = TRUE), col2hex))
#> #F0FFFF skies meet #F0FFF0 light,
#> While #FF7F50 blooms kiss morning's face.
#> #FFD700 spills across the #F5DEB3-field bright,
#> As #E6E6FA shadows lose their place.
#> #40E0D0 waters catch the sun,
#> Where #FA8072 leap through #7FFF00 streams.
#> #DA70D6 petals, one by one,
#> Fall like #DDA0DD-soft summer dreams.

Which version do you think is catchier? 🤣

Other improvements

This release includes several other useful enhancements:

  • Three new functions make it easy to convert between different programming case conventions:

    x <- "quick brown fox"
    
    str_to_camel(x)
    #> [1] "quickBrownFox"
    str_to_camel(x, first_upper = TRUE)
    #> [1] "QuickBrownFox"
    str_to_snake(x)
    #> [1] "quick_brown_fox"
    str_to_kebab(x)
    #> [1] "quick-brown-fox"
    
  • All relevant stringr functions now preserve names. This means if your input vector has names, those names will be preserved in the output:

    x <- c(first = "apple", second = "banana")
    str_to_upper(x)
    #>    first   second 
    #>  "APPLE" "BANANA"
    str_detect(x, "b")
    #>  first second 
    #>  FALSE   TRUE
    
  • A new vignette("locale-sensitive") provides detailed information about locale-sensitive functions in stringr, helping you understand how different locales affect string operations like sorting and case conversion.

Acknowledgements

A big thank you to everyone who contributed to this release! @alexanderbeatson, @allenbaron, @Anaherasm, @arnaudgallou, @AustinFournierKL, @brownj31, @ChristelSwift, @DanChaltiel, @davidciani, @davidhodge931, @Edgar-Zamora, @edward-burn, @gaborcsardi, @hadley, @jack-davison, @jdonland, @jeroenjanssens, @JFormoso, @jonovik, @KimLopezGuell, @krlmlr, @kylieainslie, @librill, @Longfei2, @LouisMPenrod, @mararva, @mgacc0, @MiguelCos, @nash-delcamp-slp, @ning-y, @Rekyt, @salim-b, @shaggycamel, @SoyAndrea, @tamimart, @tvedebrink, @VisruthSK, @warnes, and @wright13.