I'm trying to remove the numbers at the beginning of a row inside quotation marks.
> g<-"My name is Paul.\nI like playing football.\n\"55012\" And that's all."
> cat(g)
My name is Paul.
I like playing football.
"55012" And that's all.
> gsub("[\r\n]\"+[[:digit:]][^[[:space:]]]*"," ",g)
[1] "My name is Paul.\nI like playing football. 012\" And that's all."
This should work, but I don't know why only \n"55 is being replaced and not the entire number.
You closed the bracket expression with a couple of redundant [...]. [^[[:space:]]] is a sequence of [^[[:space:]] and ] patterns and matches any char other than [ and whitespace and then a ] char.
However, even that is not enough to fully fix the issue.
You may use
gsub("(^|\n)\"+[0-9]+\"+\\s*","\\1", g)
See the R demo
Pattern details
(^|\n) - start of string or a newline captured in Group 1 (referred to with \1 from the replacement pattern)
\"+ - one or more double quotes
[0-9]+ - 1+ digits
\"+ - one or more double quotes
\s* - 0+ whitespaces.
See the regex demo
Related
I'm creating a small example to be put into mutate(). Not sure why this doesn't work.
> str_extract("rs1234-<b>C</b>","^rs*\\d$")
[1] NA
I'd be great if you can point to my misunderstanding of the language instead of merely providing a solution. I expect to get "rs1234".
The ^rs*\d$ regex matches
^ - start of string
rs* - r and zero or more occurrences of s char
\d - a digit
$ - end of string.
So, your pattern matches strings like rsssss1, r3, etc.
You need
str_extract("rs1234-<b>C</b>", "^rs\\d+")
where ^rs\d+ matches rs at the start of string and then one or more digits. See this regex demo.
But if I just want the substring in between "rs" and the last number. What should I do?
You would use rs.*\d:
str_extract("rs1234-<b>C</b>", "rs.*\\d")
where rs.*\d matches rs, then any zero or more chars other than line break chars as many as possible and then a digit.
NOTE: If you need to match line endings, too, you need to prepend the last pattern with (?s) inline DOTALL modifier.
See this regex demo.
I'm trying to parse some of my chess pgn data but I'm having some trouble capturing characters just inside one bracket.
testString <- '[Event \"?\"]\n[Site \"http://www.chessmaniac.com play free chess\"]\n[Date \"2018.08.25\"]\n[Round \"-\"]\n[White \"NothingFancy 1497\"]\n[Black \"JR Smith 1985\"]\n[Result \"1-0\"]\n\n1.'
#Attempt to just get who white is, which is inside a bracket [White xxx]
findWhite <- regexpr('\\[White.*\\]', tempString)
regmatches(tempString, findWhite)
The stringr package seems to do what I want, but I'm curious what is different about the use of the same regular expression. I'm fine using stringr, but I like to also know how to do this in base R.
library(stringr)
str_extract(tempString, '\\[White.*\\]')
If you need the whole match starting with [White and ending with ] you may use
regmatches(testString, regexpr("\\[White\\s*[^][]*]", testString))
[1] "[White \"NothingFancy 1497\"]"
If you only need the substring inside double quotes:
regmatches(testString, regexpr("\\[White\\s*\\K[^][]*", testString, perl=TRUE))
[1] "\"NothingFancy 1497\""
See the regex demo.
To strip the double quotes, you may use something like
regmatches(testString, regexpr('\\[White\\s*"\\K.*(?="])', testString, perl=TRUE))
[1] "NothingFancy 1497"
See another regex demo and an online R demo.
Details
\\[ - a [ char
White - a literal substring
\\s* - 0+ whitespaces
\\K - match reset operator discarding the text matched so far
[^][]* - 0+ chars other than [ and ]
.* (in the other version) - matches any 0+ chars other than line break chars, as many as possible
(?="]) - a positive lookahead that matches a position inside a string that is immediately followed with "].
At least one way to do it in base R is to use sub and only keep the part that you want.
sub(".*\\[White\\s(*.*?)\\].*", "\\1", testString)
[1] "\"NothingFancy 1497\""
I am working in R. I am trying to import data, some use tab and some use white space between columns. My code looks like this:
gsub("[[:blank:]]", ";",
readLines(paste(PathToRecipes,recipe.files[i],sep="/")))
I read the lines of each file, and then gsub replaces all white space with a colon. Then, I will put it in a write.table and have a new set of files which I can re-import to data frame.
The problem is I get this:
"1";6;"medium;(2-1/4\";to;3-1/4\";dia.)";"Potatoes,;boiled,;cooked;without;skin,;flesh,;without;salt";11367
When I should get:
"1";6;"medium (2-1/4\" to 3-1/4\" dia.)";"Potatoes, boiled, cooked without skin, flesh, without salt";11367
There is text within quotes where white space should not be replaced with ";". How can I tell it to avoid quotes?
If the whitespaces within the text that you do not want to be replaced with semicolons are NOT tab characters then you should be able to do what you're currently doing but instead of using [[:blank:]] use \\t to replace only just the tab characters rather than all white space.
gsub("\\t", ";",readLines(paste(PathToRecipes,recipe.files[i],sep="/")))
You may use a PCRE regex with a SKIP-FAIL technique:
(*UCP)"[^"\\]*(?:\\.[^"\\]*)*"(*SKIP)(*F)|\s+
See the regex demo. Your data seeems to only have paired double quotes, so the above pattern is sufficient. Else, add a bit more to it:
(*UCP)(?<!\\)(?:\\{2})*"[^"\\]*(?:\\.[^"\\]*)*"(*SKIP)(*F)|\s+
Details
(*UCP) - make \s Unicode aware
(?<!\\) - no \ immediately to the left of the current location is allowed
(?:\\{2})* - 0+ sequences of double backslashes
" - a " char
[^"\\]* - zero or more chars other than " and \
(?:\\.[^"\\]*)* - zero or more sequences of any escape sequence and then zero or more chars other than " and \
" - a " char
(*SKIP)(*F) - omit and skip the current match starting to look for the next match from the current index (where the skipped match ended)
| - or
\s+ - matches 1 or more whitespace in any other context.
R demo:
rx <- '(*UCP)(?<!\\\\)(?:\\\\{2})*"[^"\\\\]*(?:\\\\.[^"\\\\]*)*"(*SKIP)(*F)|\\s+'
x <- c('"1"; 6; "medium (2-1/4\\" to 3-1/4\\" dia.)"; "Potatoes, boiled, cooked without skin, flesh, without salt"; 11367')
cat(gsub(rx, '', x, perl=TRUE))
## => "1";6;"medium (2-1/4\" to 3-1/4\" dia.)";"Potatoes, boiled, cooked without skin, flesh, without salt";11367
I have a following string. I tried to remove all the strings before the last space but it seems I can't achieve it.
I tried to follow this post
Use gsub remove all string before first white space in R
str <- c("Veni vidi vici")
gsub("\\s*","\\1",str)
"Venividivici"
What I want to have is only "vici" string left after removing everything before the last space.
Your gsub("\\s*","\\1",str) code replaces each occurrence of 0 or more whitespaces with a reference to the capturing group #1 value (which is an empty string since you have not specified any capturing group in the pattern).
You want to match up to the last whitespace:
sub(".*\\s", "", str)
If you do not want to get a blank result in case your string has trailing whitespace, trim the string first:
sub(".*\\s", "", trimws(str))
Or, use a handy stri_extract_last_regex from stringi package with a simple \S+ pattern (matching 1 or more non-whitespace chars):
library(stringi)
stri_extract_last_regex(str, "\\S+")
# => [1] "vici"
Note that .* matches any 0+ chars as many as possible (since * is a greedy quantifier and . in a TRE pattern matches any char including line break chars), and grabs the whole string at first. Then, backtracking starts since the regex engine needs to match a whitespace with \s. Yielding character by character from the end of the string, the regex engine stumbles on the last whitespace and calls it a day returning the match that is removed afterwards.
See the R demo and a regex demo online:
str <- c("Veni vidi vici")
gsub(".*\\s", "", str)
## => [1] "vici"
Also, you may want to see how backtracking works in the regex debugger:
Those red arrows show backtracking steps.
I have a requirement where I am working on a large data which is having double byte characters, in korean text. i want to look for a character and replace it. In order to display the korean text correctly in the browser I have changed the locale settings in R. But not sure if it gets updated for the code as well. below is my code to change locale to korean and the korean text gets visible properly in viewer, however in console it gives junk character on printing-
Sys.setlocale(category = "LC_ALL", locale = "korean")
My data is in a data.table format that contains a column with text in korean. example -
"광주광역시 동구 제봉로 49 (남동,(지하))"
I want to get rid of the 1st word which ends with "시" character. Then I want to get rid of the "(남동,(지하))" an the end. I was trying gsub, but it does not seem to be working.
New <- c("광주광역시 동구 제봉로 49 (남동,(지하))")
data <- as.data.table(New)
data[,New_trunc := gsub("\\b시", "", data$New)]
Please let me know where I am going wrong. Since I want to search the end of word, I am using \\b and since I want to replace any word ending with "시" character I am giving it as \\b시.....is this not the way to give? How to take care of () at the end of the sentence.
What would be a good source to refer to for regular expressions.
Is a utf-8 setting needed for the script as well?How to do that?
Since you need to match the letter you have at the end of the word, you need to place \b (word boundary) after the letter, so as to require a transition from a letter to a non-letter (or end of string) after that letter. A PCRE pattern that will handle this is
"\\s*\\b\\p{L}*시\\b"
Details
\\s* - zero or more whitespaces
\\b - a leading word boundary
\\p{L}* - zero or more letters
시 - your specific letter
\\b - end of the word
The second issue is that you need to remove a set of nested parentheses at the end of the string. You need again to rely on the PCRE regex (perl=TRUE) that can handle recursion with the help of a subroutine call.
> sub("\\s*(\\((?:[^()]++|(?1))*\\))$", "", New, perl=TRUE)
[1] "광주광역시 동구 제봉로 49"
Details:
\\s* - zero or more whitespaces
(\\((?:[^()]++|(?1))*\\)) - Group 1 (will be recursed) matching
\\( - a literal (
(?:[^()]++|(?1))* - zero or more occurrences of
[^()]++ - 1 or more chars other than ( and ) (possessively)
| - or
(?1) - a subroutine call that repeats the whole Group 1 subpattern
\\) - a literal )
$ - end of string.
Now, if you need to combine both, you would see that R PCRE-powered gsub does not handle Unicode chars in the pattern so easily. You must tell it to use Unicode mode with (*UCP) PCRE verb.
> gsub("(*UCP)\\b\\p{L}*시\\b|\\s*(\\((?:[^()]++|(?1))*\\))$", "", New, perl=TRUE)
[1] " 동구 제봉로 49"
Or using trimws to get rid of the leading/trailing whitespace:
> trimws(gsub("(*UCP)\\b\\p{L}*시\\b|(\\((?:[^()]++|(?1))*\\))$", "", New, perl=TRUE))
[1] "동구 제봉로 49"
See more details about the verb at PCRE Man page.