Just use re.search which stops matching once it finds a match.
re.search(r'\d+', headline).group()
or
You must remove the forward slashes present in your regex.
re.findall(r'^\D*(\d+)', headline)
Answer from Avinash Raj on Stack OverflowJust use re.search which stops matching once it finds a match.
re.search(r'\d+', headline).group()
or
You must remove the forward slashes present in your regex.
re.findall(r'^\D*(\d+)', headline)
re.search('[0-9]+', headline).group()
python - Extract the first number from a string number range - Stack Overflow
How to extract the first numbers in a string - Python - Stack Overflow
How to extract numbers from a string in Python? - Stack Overflow
How do I extract the number at the beginning of a string in Python 3.7? - Stack Overflow
Videos
If you were to solve it without regular expressions, you could have used itertools.dropwhile():
>>> from itertools import dropwhile
>>>
>>> ''.join(dropwhile(str.isdigit, "32cl2"))
'cl2'
>>> ''.join(dropwhile(str.isdigit, "4563nh3"))
'nh3'
Or, using re.sub(), replacing one or more digits at the beginning of a string:
>>> import re
>>> re.sub(r"^\d+", "", "32cl2")
'cl2'
>>> re.sub(r"^\d+", "", "4563nh3")
'nh3'
Use lstrip:
myString.lstrip('0123456789')
or
import string
myString.lstrip(string.digits)
I'd use a regexp:
>>> import re
>>> re.findall(r'\d+', "hello 42 I'm a 32 string 30")
['42', '32', '30']
This would also match 42 from bla42bla. If you only want numbers delimited by word boundaries (space, period, comma), you can use \b:
>>> re.findall(r'\b\d+\b', "he33llo 42 I'm a 32 string 30")
['42', '32', '30']
To end up with a list of numbers instead of a list of strings:
>>> [int(s) for s in re.findall(r'\b\d+\b', "he33llo 42 I'm a 32 string 30")]
[42, 32, 30]
NOTE: this does not work for negative integers
If you only want to extract only positive integers, try the following:
>>> txt = "h3110 23 cat 444.4 rabbit 11 2 dog"
>>> [int(s) for s in txt.split() if s.isdigit()]
[23, 11, 2]
I would argue that this is better than the regex example because you don't need another module and it's more readable because you don't need to parse (and learn) the regex mini-language.
This will not recognize floats, negative integers, or integers in hexadecimal format. If you can't accept these limitations, jmnas's answer below will do the trick.
As the comments on that answer note, in Python 3, filter returns a filter generator object, so you must iterate over it and build a new string before you can call int:
>>> s = '3 reviews'
>>> filter(str.isdigit, s)
<filter object at 0x800ad5f98>
>>> int(''.join(filter(str.isdigit, s)))
3
However, as other answers in that same thread point out, this is not necessarily a good way to do the job at all:
>>> s = '3 reviews in 12 hours'
>>> int(''.join(filter(str.isdigit, s)))
312
It might be better to use a regular expression matcher to find the number at the front of the string. You can then decide whether to allow signs (+ and -) and leading white-space:
>>> import re
>>> m = re.match(r'\s*([-+])?\d+', s)
>>> m
<_sre.SRE_Match object; span=(0, 1), match='3'>
>>> m.group()
'3'
>>> int(m.group())
3
Now if your string contains a malformed number, m will be None, and if it contains a sign, the sign is allowed:
>>> m = re.match(r'\s*([-+])?\d+', 'not a number')
>>> print(m)
None
>>> m = re.match(r'\s*([-+])?\d+', ' -42')
>>> m
<_sre.SRE_Match object; span=(0, 5), match=' -42'>
>>> int(m.group())
-42
If you wish to inspect what came after the number, if anything, add more to the regular expression (including some parentheses for grouping) and use m.group(1) to get the matched number. Replace \d+ with \d* to allow an empty number-match, if that's meaningful (but then be mindful of matching a lone - or + sign, if you still allow signs).
You can amend the top answer in the link you send to this:
str1 = "3158 is a great number"
print(int("".join(filter(str.isdigit, str1))))
#3158
As to why the answer doesn't work now, I'm not sure.
I am sure there are plenty of possibilities, here are a few I would consider:
thisLine <- paste(runif(11), collapse = " ")
thisLine
# [1] "0.841216114815325 0.861485596280545 0.973681036382914 0.683699210174382 0.95226536039263 0.368689567316324 0.173984130611643 0.497511914698407 0.870743532432243 0.45606177020818 0.222731305286288"
sub("\\s+.*", "", thisLine) # assumes no leading space
sub("\\s*(\\S+?)\\s.*", "\\1", thisLine) # handles leading spaces
strsplit(thisLine, " ")[[1]][1] # more flexible if you want 2nd, 3rd, ...
All give
# [1] "0.841216114815325"
You can do this very nicely with the str_first_number() function from the strex package.
library(strex)
johnsmith <- "John Smith, 34 years of age, 6ft tall, 85kg."
str_first_number(johnsmith)
#> [1] 34
str_nth_number(johnsmith, n = 1) # first number
#> [1] 34
str_nth_number(johnsmith, n = 2) # second number
#> [1] 6
str_nth_number(johnsmith, n = -1) # last number
#> [1] 85
str_last_number(johnsmith)
#> [1] 85
Created on 2018-09-03 by the reprex package (v0.2.0).
Hi I am new to Python but am working on a project where I want to extract numbers from a string. For example I have the string "CORSAIR VENGEANCE RGB 16GB (2X8GB) DDR4 3200MHZ CL 16" where I want to extract the "16" from "16GB" as well as the "2" and "8" in "(2x8GB)" and "3200" from "3200MHZ".
What is the best way to do this? Thanks in advance!
Edit: Thanks everyone for the help! Regex seems to help do the trick
You want to look into regular expressions (regex) and Python's re module.
import re
string = "CORSAIR VENGEANCE RGB 16GB (2X8GB) DDR4 3200MHZ CL 16"
matches = re.findall("(\d+)", string)
print(matches)
Output: ['16', '2', '8', '4', '3200', '16']
The regex pattern \d+ matches 1 or more numerical characters in sequence. By putting it in brackets ( ) it captures each occurrence of that pattern as a group. And the re.findall method returns those groups in a list. Note that they are still strings, not numbers.
You can use regex:
>>> import re
>>> re.findall('[0-9]+', 'CORSAIR VENGEANCE RGB 16GB (2X8GB) DDR4 3200MHZ CL 16')
['16', '2', '8', '4', '3200', '16']
You can use regex as below:
import re
str = "Owen White punt for 26 yards, downed at the army 37"
#search using regex
x = re.findall('[0-9]+', str)
print(x[0])
If you want to get 26 from 'foo123 has 26 bars', then:
val = [int(v) for v in s.split() if v.isnumeric()][0]
But if you want to get 123 instead, then:
val = int(re.search(r'\d+', s).group())