Asked  7 Months ago    Answers:  5   Viewed   33 times

I have string like this:

years<-c("20 years old", "1 years old")

I would like to grep only the numeric number from this vector. Expected output is a vector:

c(20, 1)

How do I go about doing this?



How about

# pattern is by finding a set of numbers in the start and capturing them
as.numeric(gsub("([0-9]+).*$", "\1", years))


# pattern is to just remove _years_old
as.numeric(gsub(" years old", "", years))


# split by space, get the element in first index
as.numeric(sapply(strsplit(years, " "), "[[", 1))
Tuesday, June 1, 2021
answered 7 Months ago

str_match(), from the stringr package, will do this. It returns a character matrix with one column for each group in the match (and one for the whole match):

> s = c("(sometext :: 0.1231313213)", "(moretext :: 0.111222)")
> str_match(s, "\((.*?) :: (0\.[0-9]+)\)")
     [,1]                         [,2]       [,3]          
[1,] "(sometext :: 0.1231313213)" "sometext" "0.1231313213"
[2,] "(moretext :: 0.111222)"     "moretext" "0.111222"    
Wednesday, June 2, 2021
answered 7 Months ago

What i exactly need is to find all 3 digit numbers containing 1 2 AND 3 digits

Then you can safely use

grep('^[123]{3}$', a, value=TRUE)
##=> [1] "112" "123" "113" "212" "223" "213" "312" "323" "313"

The regex matches:

  • ^ - start of string
  • [123]{3} - Exactly 3 characters that are either 1, or 2 or 3
  • $ - assert the position at the end of string.

Also, if you only need unique values, use unique.

If you do not need to allow the same digit more than once, you need a Perl-based regex:

grep('^(?!.*(.).*\1)[123]{3}$', a, value=TRUE, perl=T)
## => [1] "123" "213" "312"

Note the double escaped back-reference. The (?!.*(.).*\1) negative look-ahead will check if the string has no repeated symbols with the help of a capturing group (.) and a back-reference that forces the same captured text to appear in the string. If the same characters are found, there will be no match. See IDEONE demo.

The (?!.*(.).*\1) is a negative look-ahead. It only asserts the absence of some pattern after the current regex engine position, i.e. it checks and returns true if there is no match, otherwise it returns false. Thus, it does not not "consume" characters, it does not "match" the pattern inside the look-ahead, the regex engine stays at the same location in the input string. In this regex, it is the beginning of string (^). So, right at the beginning of the string, the regex engine starts looking for .* (any character but a newline, 0 or more repetitions), then captures 1 character (.) into group 1, again matches 0 or more characters with .*, and then tries to match the same text inside group 1 with \1. Thus, if there is 121, there will be no match since the look-ahead will return false as it will find two 1s.

Thursday, August 5, 2021
answered 4 Months ago

See the modified code below:

Sub RemoveNonDigits()
  Dim X As Long, Z As Long, LastRow As Long, CellVal As String
  Const StartRow As Long = 1
  Const DataColumn As String = "G"
  Application.ScreenUpdating = False
  LastRow = Cells(Rows.Count, DataColumn).End(xlUp).Row
  For X = StartRow To LastRow
    CellVal = Cells(X, DataColumn)
    While IsNumeric(Left(CellVal, 1))   ' Here
      CellVal = Mid(CellVal, 2)         ' all digits at the start 
    Wend                                ' are removed
    Cells(X, DataColumn) = Trim(CellVal)
  Application.ScreenUpdating = True
End Sub

That is, while the starting char in CellVal is a digit, get the substring starting with the second char, and go on until no match.

Saturday, August 28, 2021
answered 3 Months ago
mystr.match(/assignment_group=([^^]+)/)[1]; //=> "12345678901234567890123456789012"

This will find everything from the end of "assignment_group=" up to the next caret ^ symbol.

Sunday, August 29, 2021
Bojan Kseneman
answered 3 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :