codedancer
codedancer

Reputation: 1634

Remove all leading string before two specific letters in R

I am looking for a way to remove all leading strings before two specific letters "bd" and "ls".

However, I only found regex ways to remove string before white space or punctuation. Are there any ways to remove leading string before pairs of specific letters?

      date_on                          location
14 2021-02-22 bradford, west yorkshire, bd9 6dp
15 2021-02-22                     bradford, bd4
16 2021-02-22          bradford, west yorkshire
17 2021-02-22           west yorkshire, bd1 1nq
18 2021-02-22          bradford, west yorkshire
19 2021-02-22                          ls28 7he

dput:

structure(list(date_on = structure(c(18680, 18680, 18680, 18680, 
18680, 18680), class = "Date"), location = c("bradford, west yorkshire, bd9 6dp", 
"bradford, bd4", "bradford, west yorkshire", "west yorkshire, bd1 1nq", 
"bradford, west yorkshire", "ls28 7he")), row.names = 14:19, class = "data.frame")

expected outcome:

      date_on location
14 2021-02-22  bd9 6dp
15 2021-02-22      bd4
16 2021-02-22         
17 2021-02-22  bd1 1nq
18 2021-02-22         
19 2021-02-22 ls28 7he
structure(list(date_on = structure(c(18680, 18680, 18680, 18680, 
18680, 18680), class = "Date"), location = c("bd9 6dp", 
"bd4", "", "bd1 1nq", "", "ls28 7he")), row.names = 14:19, class = "data.frame")

Upvotes: 1

Views: 47

Answers (2)

Ronak Shah
Ronak Shah

Reputation: 388982

Another base R option with sub :

df$location <- sub('.*(?=bd|ls)|.*', '', df$location, perl = TRUE)
df

#      date_on location
#14 2021-02-22  bd9 6dp
#15 2021-02-22      bd4
#16 2021-02-22         
#17 2021-02-22  bd1 1nq
#18 2021-02-22         
#19 2021-02-22 ls28 7he

Remove everything before occurrence of 'bd|ls' in the string and if it doesn't occur remove everything.

Upvotes: 1

Tim Biegeleisen
Tim Biegeleisen

Reputation: 521279

We could try using sub here, for a base R option:

df$location <- sub("^.*?(\\b(?:bd|ls)\\d+.*|$)$", "\\1", df$location)
df

      date_on location
14 2021-02-22  bd9 6dp
15 2021-02-22      bd4
16 2021-02-22         
17 2021-02-22  bd1 1nq
18 2021-02-22         
19 2021-02-22 ls28 7he

Here is an explanation of the regex pattern used:

^                     from the start of the location
    .*?               consume all content up to, but not including
    (                 start capture group
        \\b(?:bd|ls)  a postal code starting in 'bd' or 'ls'
        \\d+          followed by one or more digits
        .*            consume the remainder of the location
        |             OR
        $             consume the remainder of any location NOT
                      having at least one postal code
    )                 stop capture group
$                     end of the location

Upvotes: 2

Related Questions