I am new to Python and I have a String, I want to extract the numbers from the string. For example:
str1 = "3158 reviews"
print (re.findall('\d+', str1 ))
Output is ['4', '3']
I want to get 3158 only, as an Integer preferably, not as List.
You can filter the string by digits using str.isdigit method,
>>> int(filter(str.isdigit, str1))
3158
For Python3:
int(list(filter(str.isdigit, my_str))[0])
This code works fine. There is definitely some other problem:
>>> import re
>>> str1 = "3158 reviews"
>>> print (re.findall('\d+', str1 ))
['3158']
Your regex looks correct. Are you sure you haven't made a mistake with the variable names? In your code above you mixup total_hotel_reviews_string and str.
>>> import re
>>> s = "3158 reviews"
>>>
>>> print(re.findall("\d+", s))
['3158']
IntVar = int("".join(filter(str.isdigit, StringVar)))
You were quite close to the final answer. Your re.finadall expression was only missing the enclosing parenthesis to catch all detected numbers:
re.findall( '(\d+)', str1 )
For a more general string like str1 = "3158 reviews, 432 users", this code would yield:
Output: ['3158', '432']
Now to obtain integers, you can map the int function to convert strings into integers:
A = list(map(int,re.findall('(\d+)',str1)))
Alternatively, you can use this one-liner loop:
A = [ int(x) for x in re.findall('(\d+)',str1) ]
Both methods are equally correct. They yield A = [3158, 432].
Your final result for the original question would be first entry in the array A, so we arrive at any of these expressions:
result = list(map(int,re.findall( '(\d+)' , str1 )))[0]
result = int(re.findall( '(\d+)' , str1 )[0])
Even if there is only one number present in str1, re.findall will still return a list, so you need to retrieve the first element A[0] manually.
To extract a single number from a string you can use re.search(), which returns the first match (or None):
>>> import re
>>> string = '3158 reviews'
>>> int(re.search(r'\d+', string).group(0))
3158
In Python 3.6+ you can also index into a match object instead of using group():
>>> int(re.search(r'\d+', string)[0])
3158
If the format is that simple (a space separates the number from the rest) then
int(str1.split()[0])
would do it
Best for every complex types
str1 = "sg-23.0 300sdf343fc -34rrf-3.4r" #All kinds of occurrence of numbers between strings
num = [float(s) for s in re.findall(r'-?\d+\.?\d*', str1)]
print(num)
Output:
[-23.0, 300.0, 343.0, -34.0, -3.4]
Above solutions seem to assume integers. Here's a minor modification to allow decimals:
num = float("".join(filter(lambda d: str.isdigit(d) or d == '.', inputString)
(Doesn't account for - sign, and assumes any period is properly placed in digit string, not just some english-language period lying around. It's not built to be indestructible, but worked for my data case.)
Python 2.7:
>>> str1 = "3158 reviews"
>>> int(filter(str.isdigit, str1))
3158
Python 3:
>>> str1 = "3158 reviews"
>>> int(''.join(filter(str.isdigit, str1)))
3158
There may be a little problem with code from Vishnu's answer. If there is no digits in the string it will return ValueError. Here is my suggestion avoid this:
>>> digit = lambda x: int(filter(str.isdigit, x) or 0)
>>> digit('3158 reviews')
3158
>>> digit('reviews')
0
For python3
input_str = '21ddd3322'
int(''.join(filter(str.isdigit, input_str)))
> 213322
a = []
line = "abcd 3455 ijkl 56.78 ij"
for word in line.split():
try:
a.append(float(word))
except ValueError:
pass
print(a)
OUTPUT
3455.0 56.78
I am a beginner in coding. This is my attempt to answer the questions. Used Python3.7 version without importing any libraries.
This code extracts and returns a decimal number from a string made of sets of characters separated by blanks (words).
Attention: In case there are more than one number, it returns the last value.
line = input ('Please enter your string ')
for word in line.split():
try:
a=float(word)
print (a)
except ValueError:
pass
My answer does not require any additional libraries, and it's easy to understand. But you have to notice that if there's more than one number inside a string, my code will concatenate them together.
def search_number_string(string):
index_list = []
del index_list[:]
for i, x in enumerate(string):
if x.isdigit() == True:
index_list.append(i)
start = index_list[0]
end = index_list[-1] + 1
number = string[start:end]
return number
#Use this, THIS IS FOR EXTRACTING NUMBER FROM STRING IN GENERAL.
#To get all the numeric occurences.
*split function to convert string to list and then the list comprehension
which can help us iterating through the list
and is digit function helps to get the digit out of a string.
getting number from string
use list comprehension+isdigit()
test_string = "i have four ballons for 2 kids"
print("The original string : "+ test_string)
# list comprehension + isdigit() +split()
res = [int(i) for i in test_string.split() if i.isdigit()]
print("The numbers list is : "+ str(res))
#To extract numeric values from a string in python
*Find list of all integer numbers in string separated by lower case characters using re.findall(expression,string) method.
*Convert each number in form of string into decimal number and then find max of it.
import re
def extractMax(input):
# get a list of all numbers separated by lower case characters
numbers = re.findall('\d+',input)
# \d+ is a regular expression which means one or more digit
number = map(int,numbers)
print max(numbers)
if __name__=="__main__":
input = 'sting'
extractMax(input)
you can use the below method to extract all numbers from a string.
def extract_numbers_from_string(string):
number = ''
for i in string:
try:
number += str(int(i))
except:
pass
return number
(OR) you could use i.isdigit() or i.isnumeric(in Python 3.6.5 or above)
def extract_numbers_from_string(string):
number = ''
for i in string:
if i.isnumeric():
number += str(int(i))
return number
a = '343fdfd3'
print (extract_numbers_from_string(a))
# 3433
Using a list comprehension and Python 3:
>>> int("".join([c for c in str1 if str.isdigit(c)]))
3158
Related
Let me keep it simple,
I have a string that I want it from "10fo22baar" into ["1022","fobaar"] or ["10","fo","22","baar"]
Is there a way to do something like that in Python 3 or 2?
Part 1: You can use filter with str.isdigit() to filter numeric characters as:
>>> my_str = "10fo22baar"
>>> ''.join(filter(str.isdigit, my_str))
'1022'
To get non-numeric, you can use itertools.filterfalse():
>>> from itertools import filterfalse
>>> ''.join(filterfalse(str.isdigit, my_str))
'fobaar'
# OR, for older python versions, use list comprehension:
# ''.join(c for c in my_str if not c.isdigit())
Store above values in list to get list of your desired format.
Alternatively, you can also use regex to filter out digits and alphabets into separate lists as:
import re
my_str = "10fo22baar"
# - To extract digits, use expressions as "\d+"
# - To extract alphabets, use expressions as "[a-zA-Z]+"
digits = ''.join(re.findall('\d+', my_str))
# where `digits` variable will hold string:
# '1022'
alphabets = ''.join(re.findall('[a-zA-Z]+', my_str))
# where `alphabets` variable will hold string:
# 'fobaar'
# Create your desired list from above variables:
# my_list = [digits, alphabets]
You can simplify above logic in one-line as:
my_regex = ['\d+', '[a-zA-Z]+']
my_list = [''.join(re.findall(r, my_str)) for r in my_regex]
# where `my_list` will give you:
# ['1022', 'fobaar']
Part 2: You can use itertools.groupby() to get your second desired format of list with digits and alphabets grouped together maintaining the ordwe in single list as:
from itertools import groupby
my_list = [''.join(x) for _, x in groupby(my_str, str.isdigit)]
# where `my_list` will give you:
# ['10', 'fo', '22', 'baar']
You could try to make a for loop. Like this:
str = "10fo22baar"
nums = []
chars = []
for char in str:
try:
int(char)
nums.append(char)
except ValueError:
chars.append(char)
sep = ["".join(nums), "".join(chars)]
print(sep)
Output would be: ['1022', 'fobaar']
Using string methods:
s = "10fo22baar"
num = ""
string = ""
for char in s:
if char.isnumeric():
num += str(char)
else:
string += str(char)
print(num, string)
Gives ('1022', 'fobaar')
Here's a simple and easy to understand solution.
mystring = '10fo22baar'
nums = []
chars = []
for char in mystring:
if char in ['0','1','2','3','4','5','6','7','8''9']:
nums.append(char)
else:
chars.append(char)
How it works:
We start with mystring set to the string we want to read.
We define two new lists for our numbers and regular chars.
We loop through each char in mystring.
If the current char of the loop iteration is a number, we append it to the number list.
If it's not a number, it must be a normal char. We append it to chars.
That's it
1-First, we would have to do a for to go through the entire string.
2-After that to check if the character is a number or not, we could use two methods:
string.isnumeric()
or
string.isalpha()
3-After checking, we separate the characters into lists and format them to our liking.
Our code looks like this:
myString = '10fo22baar'
charString = []
charNum = []
for char in myString:
if char.isnumeric():
charNum.append(char)
else:
charString.append(char)
myString = [''.join(charNum), ''.join(charString)]
print(myString)
I working on a simple algorithm which prints the first character who occurred twice or more.
for eg:
string ='abcabc'
output = a
string = 'abccba'
output = c
string = 'abba'
output = b
what I have done is:
string = 'abcabc'
s = []
for x in string:
if x in s:
print(x)
break
else:
s.append(x)
output: a
But its time complexity is O(n^2), how can I do this in O(n)?
Change s = [] to s = set() (and obviously the corresponding append to add). in over set is O(1), unlike in over list which is sequential.
Alternately, with regular expressions (O(n^2), but rather fast and easy):
import re
match = re.search(r'(.).*\1', string)
if match:
print(match.group(1))
The regular expression (.).*\1 means "any character which we'll remember for later, any number of intervening characters, then the remembered character again". Since regexp is scanned left-to-right, it will find a in "abba" rather than b, as required.
Use dictionaries
string = 'abcabc'
s = {}
for x in string:
if x in s:
print(x)
break
else:
s[x] = 0
or use sets
string = 'abcabc'
s = set()
for x in string:
if x in s:
print(x)
break
else:
s.add(x)
both dictionaries and sets use indexing and search in O(1)
I have a string of characters with no specific pattern. I have to look for some specific words and then extract some information.
Currently I am stuck at finding the position of the last number in a string.
So, for example if:
mystring="The total income from company xy was 12320 for the last year and 11932 in the previous year"
I want to find out the position of the last number in this string.
So the result should be "2" in position "70".
You can do this with a regular expression, here's a quick attempt:
>>>mo = re.match('.+([0-9])[^0-9]*$', mystring)
>>>print mo.group(1), mo.start(1)
2 69
This is a 0-based position, of course.
You can use a generator expression to loop over the enumerate from trailing within a next function:
>>> next(i for i,j in list(enumerate(mystring,1))[::-1] if j.isdigit())
70
Or using regex :
>>> import re
>>>
>>> m=re.search(r'(\d)[^\d]*$',mystring)
>>> m.start()+1
70
Save all the digits from the string in an array and pop the last one out of it.
array = [int(s) for s in mystring.split() if s.isdigit()]
lastdigit = array.pop()
It is faster than a regex approach and looks more readable than it.
def find_last(s):
temp = list(enumerate(s))
temp.reverse()
for pos, chr in temp:
try:
return(pos, int(chr))
except ValueError:
continue
You could reverse the string and get the first match with a simple regex:
s = mystring[::-1]
m = re.search('\d', s)
pos = len(s) - m.start(0)
I am new to Python and I have a String, I want to extract the numbers from the string. For example:
str1 = "3158 reviews"
print (re.findall('\d+', str1 ))
Output is ['4', '3']
I want to get 3158 only, as an Integer preferably, not as List.
You can filter the string by digits using str.isdigit method,
>>> int(filter(str.isdigit, str1))
3158
For Python3:
int(list(filter(str.isdigit, my_str))[0])
This code works fine. There is definitely some other problem:
>>> import re
>>> str1 = "3158 reviews"
>>> print (re.findall('\d+', str1 ))
['3158']
Your regex looks correct. Are you sure you haven't made a mistake with the variable names? In your code above you mixup total_hotel_reviews_string and str.
>>> import re
>>> s = "3158 reviews"
>>>
>>> print(re.findall("\d+", s))
['3158']
IntVar = int("".join(filter(str.isdigit, StringVar)))
You were quite close to the final answer. Your re.finadall expression was only missing the enclosing parenthesis to catch all detected numbers:
re.findall( '(\d+)', str1 )
For a more general string like str1 = "3158 reviews, 432 users", this code would yield:
Output: ['3158', '432']
Now to obtain integers, you can map the int function to convert strings into integers:
A = list(map(int,re.findall('(\d+)',str1)))
Alternatively, you can use this one-liner loop:
A = [ int(x) for x in re.findall('(\d+)',str1) ]
Both methods are equally correct. They yield A = [3158, 432].
Your final result for the original question would be first entry in the array A, so we arrive at any of these expressions:
result = list(map(int,re.findall( '(\d+)' , str1 )))[0]
result = int(re.findall( '(\d+)' , str1 )[0])
Even if there is only one number present in str1, re.findall will still return a list, so you need to retrieve the first element A[0] manually.
To extract a single number from a string you can use re.search(), which returns the first match (or None):
>>> import re
>>> string = '3158 reviews'
>>> int(re.search(r'\d+', string).group(0))
3158
In Python 3.6+ you can also index into a match object instead of using group():
>>> int(re.search(r'\d+', string)[0])
3158
If the format is that simple (a space separates the number from the rest) then
int(str1.split()[0])
would do it
Best for every complex types
str1 = "sg-23.0 300sdf343fc -34rrf-3.4r" #All kinds of occurrence of numbers between strings
num = [float(s) for s in re.findall(r'-?\d+\.?\d*', str1)]
print(num)
Output:
[-23.0, 300.0, 343.0, -34.0, -3.4]
Above solutions seem to assume integers. Here's a minor modification to allow decimals:
num = float("".join(filter(lambda d: str.isdigit(d) or d == '.', inputString)
(Doesn't account for - sign, and assumes any period is properly placed in digit string, not just some english-language period lying around. It's not built to be indestructible, but worked for my data case.)
Python 2.7:
>>> str1 = "3158 reviews"
>>> int(filter(str.isdigit, str1))
3158
Python 3:
>>> str1 = "3158 reviews"
>>> int(''.join(filter(str.isdigit, str1)))
3158
There may be a little problem with code from Vishnu's answer. If there is no digits in the string it will return ValueError. Here is my suggestion avoid this:
>>> digit = lambda x: int(filter(str.isdigit, x) or 0)
>>> digit('3158 reviews')
3158
>>> digit('reviews')
0
For python3
input_str = '21ddd3322'
int(''.join(filter(str.isdigit, input_str)))
> 213322
a = []
line = "abcd 3455 ijkl 56.78 ij"
for word in line.split():
try:
a.append(float(word))
except ValueError:
pass
print(a)
OUTPUT
3455.0 56.78
I am a beginner in coding. This is my attempt to answer the questions. Used Python3.7 version without importing any libraries.
This code extracts and returns a decimal number from a string made of sets of characters separated by blanks (words).
Attention: In case there are more than one number, it returns the last value.
line = input ('Please enter your string ')
for word in line.split():
try:
a=float(word)
print (a)
except ValueError:
pass
My answer does not require any additional libraries, and it's easy to understand. But you have to notice that if there's more than one number inside a string, my code will concatenate them together.
def search_number_string(string):
index_list = []
del index_list[:]
for i, x in enumerate(string):
if x.isdigit() == True:
index_list.append(i)
start = index_list[0]
end = index_list[-1] + 1
number = string[start:end]
return number
#Use this, THIS IS FOR EXTRACTING NUMBER FROM STRING IN GENERAL.
#To get all the numeric occurences.
*split function to convert string to list and then the list comprehension
which can help us iterating through the list
and is digit function helps to get the digit out of a string.
getting number from string
use list comprehension+isdigit()
test_string = "i have four ballons for 2 kids"
print("The original string : "+ test_string)
# list comprehension + isdigit() +split()
res = [int(i) for i in test_string.split() if i.isdigit()]
print("The numbers list is : "+ str(res))
#To extract numeric values from a string in python
*Find list of all integer numbers in string separated by lower case characters using re.findall(expression,string) method.
*Convert each number in form of string into decimal number and then find max of it.
import re
def extractMax(input):
# get a list of all numbers separated by lower case characters
numbers = re.findall('\d+',input)
# \d+ is a regular expression which means one or more digit
number = map(int,numbers)
print max(numbers)
if __name__=="__main__":
input = 'sting'
extractMax(input)
you can use the below method to extract all numbers from a string.
def extract_numbers_from_string(string):
number = ''
for i in string:
try:
number += str(int(i))
except:
pass
return number
(OR) you could use i.isdigit() or i.isnumeric(in Python 3.6.5 or above)
def extract_numbers_from_string(string):
number = ''
for i in string:
if i.isnumeric():
number += str(int(i))
return number
a = '343fdfd3'
print (extract_numbers_from_string(a))
# 3433
Using a list comprehension and Python 3:
>>> int("".join([c for c in str1 if str.isdigit(c)]))
3158
I have a string s with nested brackets: s = "AX(p>q)&E((-p)Ur)"
I want to remove all characters between all pairs of brackets and store in a new string like this: new_string = AX&E
i tried doing this:
p = re.compile("\(.*?\)", re.DOTALL)
new_string = p.sub("", s)
It gives output: AX&EUr)
Is there any way to correct this, rather than iterating each element in the string?
Another simple option is removing the innermost parentheses at every stage, until there are no more parentheses:
p = re.compile("\([^()]*\)")
count = 1
while count:
s, count = p.subn("", s)
Working example: http://ideone.com/WicDK
You can just use string manipulation without regular expression
>>> s = "AX(p>q)&E(qUr)"
>>> [ i.split("(")[0] for i in s.split(")") ]
['AX', '&E', '']
I leave it to you to join the strings up.
>>> import re
>>> s = "AX(p>q)&E(qUr)"
>>> re.compile("""\([^\)]*\)""").sub('', s)
'AX&E'
Yeah, it should be:
>>> import re
>>> s = "AX(p>q)&E(qUr)"
>>> p = re.compile("\(.*?\)", re.DOTALL)
>>> new_string = p.sub("", s)
>>> new_string
'AX&E'
Nested brackets (or tags, ...) are something that are not possible to handle in a general way using regex. See http://www.amazon.de/Mastering-Regular-Expressions-Jeffrey-Friedl/dp/0596528124/ref=sr_1_1?ie=UTF8&s=gateway&qid=1304230523&sr=8-1-spell for details why. You would need a real parser.
It's possible to construct a regex which can handle two levels of nesting, but they are already ugly, three levels will already be quite long. And you don't want to think about four levels. ;-)
You can use PyParsing to parse the string:
from pyparsing import nestedExpr
import sys
s = "AX(p>q)&E((-p)Ur)"
expr = nestedExpr('(', ')')
result = expr.parseString('(' + s + ')').asList()[0]
s = ''.join(filter(lambda x: isinstance(x, str), result))
print(s)
Most code is from: How can a recursive regexp be implemented in python?
You could use re.subn():
import re
s = 'AX(p>q)&E((-p)Ur)'
while True:
s, n = re.subn(r'\([^)(]*\)', '', s)
if n == 0:
break
print(s)
Output
AX&E
this is just how you do it:
# strings
# double and single quotes use in Python
"hey there! welcome to CIP"
'hey there! welcome to CIP'
"you'll understand python"
'i said, "python is awesome!"'
'i can\'t live without python'
# use of 'r' before string
print(r"\new code", "\n")
first = "code in"
last = "python"
first + last #concatenation
# slicing of strings
user = "code in python!"
print(user)
print(user[5]) # print an element
print(user[-3]) # print an element from rear end
print(user[2:6]) # slicing the string
print(user[:6])
print(user[2:])
print(len(user)) # length of the string
print(user.upper()) # convert to uppercase
print(user.lstrip())
print(user.rstrip())
print(max(user)) # max alphabet from user string
print(min(user)) # min alphabet from user string
print(user.join([1,2,3,4]))
input()