String remove up to last "}"

Viewed 83

Rvest output is inserting a long string of extra data in one of the cells:

QC1 <- read_html("https://en.wikipedia.org/wiki/List_of_airports_in_Quebec")%>% 
  html_node('body #content #bodyContent #mw-content-text .mw-parser-output table') %>% 
  html_table(fill = TRUE) 

QC1$Coordinates first cell starts with: .mw-parser-output .geo-default,.mw-parser-output .geo-dms,.mw-parser-output .geo-dec{display:inline}.mw-parser-output .geo-nondefault,.mw-parser-output .geo-multi-punct{display:none}.mw-parser-output .longitude,.mw-parser-output .latitude{white-space:nowrap}60°49′07″N 078°08′55″W / 60.81861°N 78.14861°W / 60.81861; -78.14861 (Akulivik Airport)

and all other cells start with the numeric coordinate data. I have tried str_remove but I find the fruit-based examples in the documentation limited and unhelpful when dealing with more complicated regex than "banana".

I'd like to delete everything from that first Coordinate cell until the LAST "}". I thought I could add a pipe with str_remove(., "^.*}") or gsub but it hasn't worked. Any suggestions?

2 Answers

You can use

library(textreadr)
library(dplyr)
library(rvest)

QC1 <- read_html("https://en.wikipedia.org/wiki/List_of_airports_in_Quebec")%>% 
   html_node('body #content #bodyContent #mw-content-text .mw-parser-output table') %>% 
   html_table(fill = TRUE) 

QC1$Coordinates <- sub(".*}", "", QC1$Coordinates)

The first item will look as expected:

> QC1$Coordinates[1]
[1] "60°49′07″N 078°08′55″W / 60.81861°N 78.14861°W / 60.81861; -78.14861 (Akulivik Airport)"

The sub(".*}", "", QC1$Coordinates) code line removes all text up to the last } including the char.

NOTE: The regex engine used by sub/gsub by defaul is TRE, and this regex engine does not require a } char to be escaped, it is not a special regex metacharacter there. However, str_remove requires } to be escaped because the regex engine used in stringr/stringi functions is ICU, and this regex engine is rather different from both TRE and PCRE commonly used in gsub/sub, etc. base R functions.

So, you can also use

str_remove(., "^.*\\}")
str_remove(., "(?s)^.*\\}") ## If there are line breaks before last }
str_remove(., "^.*[}]")     ## Inside brackets, } is not special

I was getting Error in stri_replace_first_regex(string, pattern, fix_replacement(replacement), : Syntax error in regexp pattern. (U_REGEX_RULE_SYNTAX) because } is a special character (thanks to LukeA)

So QC1$Coordinates %<>% str_remove(., pattern="^.*\\}") or QC1$Coordinates %<>% sub(".*}", "", .) are functionally equivalent (thanks to Wiktor for the alternative). Seems sub() doesn't freak out with } for some reason.

Related