This question already has answers here:
What is the difference between re.search and re.match?
(9 answers)
Closed 3 years ago.
I have this string:
field = 1400 x 3524
I want to take these numbers into two seperate variables so I can perform multiplication. This is how I do it:
num1 = re.match("(\d{3,4})(?= x)", field).group(1)
num2 = re.match("(?<=x )(\d{3,4})", field).group(1)
I works with the first number, but the second number comes out as a NoneType.
What am I doing wrong?
Try this:
>>> import re
>>> a = 'field = 1400 x 3524'
>>> m = re.findall( r'\d+', a )
>>> m
['1400', '3524']
>>>
re module documentation states that:
Note that patterns which start with positive lookbehind assertions
will not match at the beginning of the string being searched; you will
most likely want to use the search() function rather than the match()
function
In your case that means you should do:
import re
field = "1400 x 3524"
num2 = re.search("(?<=x )(\d{3,4})", field).group(0)
print(num2) # 3524
Note that here beyond changing match to search I also changed group(1) to group(0)
Related
This question already has answers here:
Python replace string pattern with output of function
(4 answers)
Closed 5 years ago.
Say I have the following string:
mystr = "6374696f6e20????28??????2c??2c????29"
And I want to replace every sequence of "??" with its length\2. So for the example above, I want to get the following result:
mystr = "6374696f6e2022832c12c229"
Meaning:
???? replaced with 2
?????? replaced with 3
?? replaced with 1
???? replaced with 2
I tried the following but I'm not sure it's the good approach, and anyway -- it doesn't work:
regex = re.compile('(\?+)')
matches = regex.findall(mystr)
if matches:
for match in matches:
match_length = len(match)/2
if (match_length > 0):
mystr= regex .sub(match_length , mystr)
You can use a callback function in Python's re.sub. FYI lambda expressions are shorthand to create anonymous functions.
See code in use here
import re
mystr = "6374696f6e20????28??????2c??2c????29"
regex = re.compile(r"\?+")
print(re.sub(regex, lambda m: str(int(len(m.group())/2)), mystr))
There seems to be uncertainty about what should happen in the case of ???. The above code will result in 1 since it converts to int. Without int conversion the result would be 1.0. If you want to ??? to become 1? you can use the pattern (?:\?{2})+ instead.
This question already has answers here:
Check if a string contains a number
(20 answers)
Closed 7 years ago.
I am a newbie in Python. I am making a program where I take a input from user and check if any number is inside in the string. I am checking it by taking it in a variable. Is it not correct to check via a VARIABLE?
user_string=input("Enter the Word:")
print (user_string)
for index in (0,9):
number=str(index) #Typecasting Int to String
if number in user_string: #Check if Number exist in the string
print ("yes")
output:
Enter the Word:helo2
helo2
You can use the string method isdigit() on each character in a generator expression within any. This will short-circuit upon finding the first numeric character (if one is present)
>>> user_string = 'helo2'
>>> any(i.isdigit() for i in user_string)
True
>>> user_string = 'hello'
>>> any(i.isdigit() for i in user_string)
False
Look at your for-loop. You are looping over a tuple (0,9). So actually you are only testing for 0 and 9. Use range(10) instead.
More elegant, to get the numbers inside your string, you can use sets:
import string
print 'yes' if set(string.digits).intersection(user_string) else 'no'
This question already has answers here:
How do I reverse a string in Python?
(19 answers)
Closed 2 years ago.
I am working on a script that takes the user input and reverses the whole input.
for example if the user inputs "London" it will be printed as "nodnol" . I am currently being able to reverse the order of a certain number of letters but not being able to reverse the entire string .
You can reverse it with the slicing syntax:
s = input("Enter a string: ")
print s[::-1]
Enter a string: London
nodnoL
print raw_input().lower()[::-1]
I'm under the impression that you cannot use any of the nice things that make Python a soo nice language, so here it is my low-key answer...
At the beginning, we have a string,
>>> ast = input('Tell me a word of your choice: ') # <--- "London"
We can compute its length using the len builtin
>>> last = len(ast) # <--- 6
now we want to index the string in reverse, the string indices are 0 ... 5 so we need the sequence 5 4 3 2 1 0
>>> for i in range(last): print(last-1-i)
5
4
3
2
1
0
Let's see that we can access the characters of the string in reverse using the indexing scheme above
>>> for i in range(last): print(ast[last-1-i])
n
o
d
n
o
L
Finally, we have to build the reversed string, using the + operator and starting from the null string
>>> rast = ""
>>> for i in range(last): rast += ast[last-1-i]
>>> print(rast)
nodnoL
>>>
To summarize
ast = input('Tell me a word of your choice: ')
last = len(ast)
rast = ""
for i in range(last):
rast += ast[last-1-i]
s = input("Enter a string: ")
s = s.lower()
print s[::-1]
string=input('Enter String: ')
print (string[::-1])
string: heaven
output:nevaeh
Using extended slice syntax: 'string_goes_here'[::-1]
Example : print('london'[::-1])
Online Compiler link
Extended Slices :
Ever since Python 1.4, the slicing syntax has supported an optional
third step'' orstride'' argument. For example, these are all
legal Python syntax: L[1:10:2], L[:-1:1], L[::-1]. This was added to
Python at the request of the developers of Numerical Python, which
uses the third argument extensively. However, Python's built-in list,
tuple, and string sequence types have never supported this feature,
raising a TypeError if you tried it. Michael Hudson contributed a
patch to fix this shortcoming.
--Reference
This question already has answers here:
re.sub replace with matched content
(4 answers)
Closed 8 years ago.
I want to replace the digits in the middle of telephone with regex but failed. Here is my code:
temp= re.sub(r'1([0-9]{1}[0-9])[0-9]{4}([0-9]{4})', repl=r'$1****$2', tel_phone)
print temp
In the output, it always shows:
$1****$2
But I want to show like this: 131****1234. How to accomplish it ? Thanks
I think you're trying to replace four digits present in the middle (four digits present before the last four digits) with ****
>>> s = "13111111234"
>>> temp= re.sub(r'^(1[0-9]{2})[0-9]{4}([0-9]{4})$', r'\1****\2', s)
>>> print temp
131****1234
You might have seen $1 in replacement string in other languages. However, in Python, use \1 instead of $1. For correctness, you also need to include the starting 1 in the first capturing group, so that the output also include the starting 1; otherwise, the starting 1 will be lost.
This question already has answers here:
How can I find the number of overlapping sequences in a String with Python? [duplicate]
(4 answers)
Closed 9 years ago.
I wanted to count the number of times that a string like 'aa' appears in 'aaa' (or 'aaaa').
The most obvious code gives the wrong (or at least, not the intuitive) answer:
'aaa'.count('aa')
1 # should be 2
'aaaa'.count('aa')
2 # should be 3
Does anyone have a simple way to fix this?
From str.count() documentation:
Return the number of non-overlapping occurrences of substring sub in the range [start, end]. Optional arguments start and end are interpreted as in slice notation.
So, no. You are getting the expected result.
If you want to count number of overlapping matches, use regex:
>>> import re
>>>
>>> len(re.findall(r'(a)(?=\1)', 'aaa'))
2
This finds all the occurrence of a, which is followed by a. The 2nd a wouldn't be captured, as we've used look-ahead, which is zero-width assertion.
haystack = "aaaa"
needle = "aa"
matches = sum(haystack[i:i+len(needle)] == needle
for i in xrange(len(haystack)-len(needle)+1))
# for Python 3 use range instead of xrange
The solution is not taking overlap into consideration.
Try this:
big_string = "aaaa"
substring = "aaa"
count = 0
for char in range(len(big_string)):
count += big_string[char: char + len(subtring)] == substring
print count
You have to be careful, because you seem to looking for non-overlapping substrings. To fix this I'd do:
len([s.start() for s in re.finditer('(?=aa)', 'aaa')])
And if you don't care about the position where the substring starts you can do:
len([_ for s in re.finditer('(?=aa)', 'aaa')])
Although someone smarter than myself might be able to show that there are performances differences :)