bretauv
bretauv

Reputation: 8567

Insert some characters in a specific place with a regex

I have a string of the following form:

text <- "\\usage{afunction(arg = list())anotherfunction()}\\somethingelse{}"

I would like to insert \\n between afunction() and anotherfunction(). Expected output:

"\\usage{afunction(arg = list()) \\n anotherfunction()}\\somethingelse{}"

Here's what I have so far:

text <- "\\usage{afunction(arg = list())anotherfunction()}\\somethingelse{}"

pattern <- "(?<=usage\\{)[^\\}]+"

temp <- regmatches(text, gregexpr(pattern, text, perl = TRUE)) 

gsub("\\)", ") \\\\n ", temp, perl = TRUE)

which gives

"afunction(arg = list() \\n ) \\n anotherfunction() \\n "

The problems are that there is \\n just after list(), and that the rest of the original expression is gone.

How can I do that? (I would prefer a solution in base R)

Upvotes: 0

Views: 60

Answers (2)

Wiktor Stribiżew
Wiktor Stribiżew

Reputation: 627410

If there are no arbitrary string variables or comments in between, you can use a recursion-based pattern like

usage\{\w+(\((?:[^()]++|(?1))*\))\K

See the regex demo. Details:

  • usage\{ - a usage{ string
  • \w+ - one or more word chars
  • (\((?:[^()]++|(?1))*\)) - Group 1: a string between parentheses that may contain nested paired parentheses
  • \K - a match reset operator.

See the R demo:

text <- "\\usage{afunction(arg = list())anotherfunction()}\\somethingelse{}"
pattern <- "usage\\{\\w+(\\((?:[^()]++|(?1))*\\))\\K"
gsub( pattern, " \\\\n ", text, perl=TRUE ) 
# => [1] "\\usage{afunction(arg = list()) \\n anotherfunction()}\\somethingelse{}"

Upvotes: 2

Andrew
Andrew

Reputation: 5138

Assuming there will always be no space between the close parentheses and the beginning of a new function (starting with an upper- or lower-case letter), you could use this. This also assumes that you will always want to insert a newline when there is a close parentheses immediately followed by a letter.

text <- "\\usage{afunction(arg = list())anotherfunction()}\\somethingelse{}"

gsub("(\\))([A-Za-z])", "\\1 \\\\n \\2", text)
# [1] "\\usage{afunction(arg = list()) \\n anotherfunction()}\\somethingelse{}"

Upvotes: 1

Related Questions