2

I'd like to replace all the cases of the word Date in a string unless it is Date() (that is Date followed by parenthesis). Here's an example of a string and what I tried at first:

x <- c("frDate", "Date()", "Date", "Sys.Date()")
gsub("Date", paste("Date:", Sys.Date()), x)

What I get:

> gsub("Date", paste("Date:", Sys.Date()), x)
[1] "frDate: 2013-04-04"     "Date: 2013-04-04()"     "Date: 2013-04-04"      
[4] "Sys.Date: 2013-04-04()"

What I'd like:

> gsub("Date", paste("Date:", Sys.Date()), x)
[1] "frDate: 2013-04-04"     "Date()"     "Date: 2013-04-04"      
[4] "Sys.Date()"

I thought maybe I could learn from my previous question on the matter:

gsub("(?=[^Date\\(\\)[^Date]])", paste("Date:", Sys.Date()), x)

Not so good.

If someone has a better title to make this solution more general please change it so R regex users have a searchable means of handling exceptions.

Community
  • 1
  • 1
Tyler Rinker
  • 108,132
  • 65
  • 322
  • 519
  • Is it possible the input will have the form "blah blah Date blah"? – Dason Apr 04 '13 at 16:10
  • In my case no but I was hoping to make a thread that was more generalizable to others Dason so let's pretend yes. – Tyler Rinker Apr 04 '13 at 16:13
  • @Stedy I agree with the first part of your title change (and kept it) but the later part (with same name as built in) was just coincidental, it could have been `chicken` followed by `@`. I coudn't find a thread here for R users that specifically addressed this problem (though I'm sure there is) and so I want to have one that has a title that's easy to search for. – Tyler Rinker Apr 04 '13 at 16:19
  • good point, this is much better than mine – Stedy Apr 04 '13 at 16:21

2 Answers2

6

Just add to your pattern a negative lookahead assertion that matches an opening parenthesis. (You'll also have to set perl=TRUE to get this functionality.)

gsub("Date(?!\\()", paste("Date:", Sys.Date()), x, perl=TRUE)
[1] "frDate: 2013-04-04" "Date()"             "Date: 2013-04-04"  
[4] "Sys.Date()"   

The name sounds intimidating, and I suspect the #@!$%^&*-like strings of symbols scare folks away, but it's really not that complicated: just type (?!...), replacing ... by whatever pattern you would like to cause the entire regex not to match. Here, we'd like any string that starts out with Date but then continues with ( not to match, so (escaping ( because it's a special character) we write (?!\\)).

Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
  • Both responses are very helpful. Thank you for taking the time to explain this out in detail. – Tyler Rinker Apr 04 '13 at 16:25
  • 1
    De nada. The four look-around assertions are so incredibly useful that I think it's worth taking 15-30 to play around with all four of them. That should be enough to make them a permanent part of your repertoire! – Josh O'Brien Apr 04 '13 at 16:31
  • is this a decent looking tutorial or did you have something else in mind: http://docs.racket-lang.org/guide/Looking_Ahead_and_Behind.html? – Tyler Rinker Apr 05 '13 at 01:25
  • 1
    @TylerRinker Yeah, that looks fine. I tend to really like [this site](http://www.regular-expressions.info/), and so (apparently) do lots of other folks. [Here's the section](http://www.regular-expressions.info/lookaround.html) devoted to lookaround assertions. – Josh O'Brien Apr 05 '13 at 03:49
3

gsub('Date$', paste('Date:', Sys.Date()), x) work for you?

# [1] "frDate: 2013-04-04" "Date()" "Date: 2013-04-04"   "Sys.Date()"   

The $ operator in regular expressions indicates end of line. This way, only values in x that end with Date are matched. If you had a situation where you could have blah blah Date blah that you also wanted to match the regex would get significantly more complex.

You could also match Date followed by anything other than a ( like this:

gsub('Date(?!\\()', paste('Date:', Sys.Date()), x, perl=TRUE)

Where the ? marks the following as optional and the ! is a negation of sorts.

Justin
  • 42,475
  • 9
  • 93
  • 111
  • thank you for taking the time to explain this in detail. Hopefully this will be a thread that others can find useful with similar needs. +1 – Tyler Rinker Apr 04 '13 at 16:26