Python string replace blackslash w character - python-3.x

I'm trying to perform string replace that contain backsplash with a character. Any able to guide how to handle backsplash with a character
string= 'decimal("\t",0) Amount = 0;'
print(string.replace('\t','\0')) #tried: print(string.replace('"\\t"','"\\0"'))
expected output
decimal("\0",0) Amount = 0;
current output
decimal(" ",0) Amount = 0;

Given:
>>> string= 'decimal("\t",0) Amount = 0;'
You can use the literal \ with '\\' and do:
>>> print(string.replace('\t','\\0'))
decimal("\0",0) Amount = 0;
Careful not to confuse what is printed with its interpreter representation which will be the double backslash form:
>>> string.replace('\t','\\0')
'decimal("\\0",0) Amount = 0;'
Also understand that '\t' is a single character; a tab. The character '\0' is also a single character; a NUL:
>>> len('\t')
1
>>> len('\0')
1
What you need is the two character string '\\0' which in turn will be printed as '\0' even though that is not a NUL:
>>> len('\\0')
2
>>> '\\0'=='\0'
False
As an alternative to '\\0' you can also use a raw string:
>>> '\\0'==r'\0'
True
Which you use is a matter of preference (I use the r form exclusively for regex for example and personally prefer \\ for applications like this) but it is a form you should know.

Related

Is there a way to replace characters in a string from index 0 to index -4 (i.e. all but last 4 characters) with a '#'

For example, If my string was 'HelloWorld'
I want the output to be ######orld
My Code:
myString = 'ThisIsAString'
hashedString = string.replace(string[:-4], '#')
print(hashedString)
Output >> #ring
I expected the output to have just one # symbol since it is replacing argument 1 with argument 2.
Can anyone help me with this?
You could multiply # by the word length - 4 and then use the string slicing.
myString = 'HelloWorld'
print('#' * (len(myString) - 4) + myString[-4:])
myString = 'ThisIsAString'
print('#' * (len(myString) - 4) + myString[-4:])
string.replace(old, new) replaces all instances of old with new. So the code you provided is actually replacing the entire beginning of the string with a single pound sign.
You will also notice that input like abcdabcd will give the output ##, since you are replacing all 'abcd' substrings.
Using replace, you could do
hashes = '#' * len(string[:-4])
hashedString = string.replace(string[:-4], hashes, 1)
Note the string multiplication to get the right number of pound symbols, and the 1 passed to replace, which tells it only to replace the first case it finds.
A better method would be to not use replace at all:
hashes = '#' * (len(string) - 4)
leftover = string[-4:]
hashedString = hashes + leftover
This time we do the same work with getting the pound sign string, but instead of replacing we just take the last 4 characters and add them after the pound signs.

How to better code, when looking for substrings?

I want to extract the currency (along with the $ sign) from a list, and create two different currency lists which I have done. But is there a better way to code this?
The list is as below:
['\n\n\t\t\t\t\t$59.90\n\t\t\t\t\n\n\n\t\t\t\t\t\t$68.00\n\t\t\t\t\t\n\n',
'\n\n\t\t\t\t\t$55.00\n\t\t\t\t\n\n\n\t\t\t\t\t\t$68.00\n\t\t\t\t\t\n\n',
'\n\n\t\t\t\t\t$38.50\n\t\t\t\t\n\n\n\t\t\t\t\t\t$49.90\n\t\t\t\t\t\n\n',
'\n\n\t\t\t\t\t$49.00\n\t\t\t\t\n\n\n\t\t\t\t\t\t$62.00\n\t\t\t\t\t\n\n',
'\n\n\t\t\t\t\t$68.80\n\t\t\t\t\n\n',
'\n\n\t\t\t\t\t$49.80\n\t\t\t\t\n\n\n\t\t\t\t\t\t$60.50\n\t\t\t\t\t\n\n']
Python code:
pp_list = []
up_list = []
for u in usual_price_list:
rep = u.replace("\n","")
rep = rep.replace("\t","")
s = rep.rsplit("$",1)
pp_list.append(s[0])
up_list.append("$"+s[1])
For this kind of problem, I tend to use a lot the re module, as it is more readable, more maintainble and does not depend on which character surround what you are looking for :
import re
pp_list = []
up_list = []
for u in usual_price_list:
prices = re.findall(r"\$\d{2}\.\d{2}", u)
length_prices = len(prices)
if length_prices > 0:
pp_list.append(prices[0])
if length_prices > 1:
up_list.append(prices[1])
Regular Expresion Breakdown
$ is the end of string character, so we need to escape it
\d matches any digit, so \d{2} matches exactly 2 digits
. matches any character, so we need to escape it
If you want it you can modify the number of digits for the cents with \d{1,2} for matches one or two digits, or \d* to match 0 digit or more
As already pointed for doing that task re module is useful - I would use re.split following way:
import re
data = ['\n\n\t\t\t\t\t$59.90\n\t\t\t\t\n\n\n\t\t\t\t\t\t$68.00\n\t\t\t\t\t\n\n',
'\n\n\t\t\t\t\t$55.00\n\t\t\t\t\n\n\n\t\t\t\t\t\t$68.00\n\t\t\t\t\t\n\n',
'\n\n\t\t\t\t\t$38.50\n\t\t\t\t\n\n\n\t\t\t\t\t\t$49.90\n\t\t\t\t\t\n\n',
'\n\n\t\t\t\t\t$49.00\n\t\t\t\t\n\n\n\t\t\t\t\t\t$62.00\n\t\t\t\t\t\n\n',
'\n\n\t\t\t\t\t$68.80\n\t\t\t\t\n\n',
'\n\n\t\t\t\t\t$49.80\n\t\t\t\t\n\n\n\t\t\t\t\t\t$60.50\n\t\t\t\t\t\n\n']
prices = [re.split(r'[\n\t]+',i) for i in data]
prices0 = [i[1] for i in prices]
prices1 = [i[2] for i in prices]
print(prices0)
print(prices1)
Output:
['$59.90', '$55.00', '$38.50', '$49.00', '$68.80', '$49.80']
['$68.00', '$68.00', '$49.90', '$62.00', '', '$60.50']
Note that this will work assuming that there are solely \n and \t excluding prices and there is at least one \n or \t before first price and at least one \n or \t between prices.
[\n\t]+ denotes any string made from \n or \t with length 1 or greater, that is \n, \t, \n\n, \t\t, \n\t, \t\n and so on

Find and append characters of a String by matching with a List in Python 2.7

There is a list contains with character sequences such below:
seq_list = ['C','CA','CAF','CMMVF','E','CMM','CMMF','CMMFF',...]
and a string can be defined as below:
a_str = 'CAFCMMVFCMMECMMFFCCAF'
The problem is to match the longest character sequence of seq_list in a_str from left to right iteratively, and then a character('|') should be appended if it's found.
For example,
a_str begins with 'C' but the actual character sequence is 'CAF' because 'CAF' has the longer sequence than 'C',
so that it should be achieved such below:
a_str = 'CAF|CMMVFCMMECMMFFCCAF' #actual sequence match
'C|AFCMMVFCMMECMMFFCCAF' #false sequence match
Then, remaining a_str_r should be like this a_str_r = 'CMMVFCMMECMMFFCCAF' after a character '|' has been appended. So that the iterative process has to start over again by matching the longest sequence from the list until the end of the string, and the final result should be like this:
a_str = 'CAF|CMMVF|CMM|E|CMMFF|C|CAF|'
This was one of the attempts for this problem, and still couldn't get right!
a_str_r = []
for each in seq_list:
for i in a_str:
if each in i:
a_str_r.append(i+'|')
return a_str_r
You want to search for leftmost longest match. That is a standout for a regular expression search.
import re
seq_list = ['C','CA','CAF','CMMVF','E','CMM','CMMF','CMMFF']
# Sort to put longer match strings before shorter ones
sseq_list = sorted(seq_list, key=lambda a: len(a), reverse=True)
# Turn list into a regular expression string
sseq_re = '|'.join(sseq_list)
# Compile regular expression string
rx = rx = re.compile(sseq_re)
# Put pipe characters between the matches
print '|'.join(rx.findall('CAFCMMVFCMMECMMFFCCAF'))

How can I delete the letter that occurs in the two strings using python?

That's the source code:
def revers_e(str_one,str_two):
for i in range(len(str_one)):
for j in range(len(str_two)):
if str_one[i] == str_two[j]:
str_one = (str_one - str_one[i]).split()
print(str_one)
else:
print('There is no relation')
if __name__ == '__main__':
str_one = input('Put your First String: ').split()
str_two = input('Put your Second String: ')
print(revers_e(str_one, str_two))
How can I remove a letter that occurs in both strings from the first string then print it?
How about a simple pythonic way of doing it
def revers_e(s1, s2):
print(*[i for i in s1 if i in s2]) # Print all characters to be deleted from s1
s1 = ''.join([i for i in s1 if i not in s2]) # Delete them from s1
This answer says, "Python strings are immutable (i.e. they can't be modified). There are a lot of reasons for this. Use lists until you have no choice, only then turn them into strings."
First of all you don't need to use a pretty suboptimal way using range and len to iterate over a string since strings are iterable you can just iterate over them with a simple loop.
And for finding intersection within 2 string you can use set.intersection which returns all the common characters in both string and then use str.translate to remove your common characters
intersect=set(str_one).intersection(str_two)
trans_table = dict.fromkeys(map(ord, intersect), None)
str_one.translate(trans_table)
def revers_e(str_one,str_two):
for i in range(len(str_one)):
for j in range(len(str_two)):
try:
if str_one[i] == str_two[j]:
first_part=str_one[0:i]
second_part=str_one[i+1:]
str_one =first_part+second_part
print(str_one)
else:
print('There is no relation')
except IndexError:
return
str_one = input('Put your First String: ')
str_two = input('Put your Second String: ')
revers_e(str_one, str_two)
I've modified your code, taking out a few bits and adding a few more.
str_one = input('Put your First String: ').split()
I removed the .split(), because all this would do is create a list of length 1, so in your loop, you'd be comparing the entire string of the first string to one letter of the second string.
str_one = (str_one - str_one[i]).split()
You can't remove a character from a string like this in Python, so I split the string into parts (you could also convert them into lists like I did in my other code which I deleted) whereby all the characters up to the last character before the matching character are included, followed by all the characters after the matching character, which are then appended into one string.
I used exception statements, because the first loop will use the original length, but this is subject to change, so could result in errors.
Lastly, I just called the function instead of printing it too, because all that does is return a None type.
These work in Python 2.7+ and Python 3
Given:
>>> s1='abcdefg'
>>> s2='efghijk'
You can use a set:
>>> set(s1).intersection(s2)
{'f', 'e', 'g'}
Then use that set in maketrans to make a translation table to None to delete those characters:
>>> s1.translate(str.maketrans({e:None for e in set(s1).intersection(s2)}))
'abcd'
Or use list comprehension:
>>> ''.join([e for e in s1 if e in s2])
'efg'
And a regex to produce a new string without the common characters:
>>> re.sub(''.join([e for e in s1 if e in s2]), '', s1)
'abcd'

How to Print a string to a specific character?

I have a file like this:
NA|polymerase|KC545393|Bundibugyo_ebolavirus|EboBund_112_2012|NA|2012|Human|Democratic_Republic_of_the_Congo
NA|VP24|KC545393|Bundibugyo_ebolavirus|EboBund_112_2012|NA|2012|Human|Democratic_Republic_of_the_Congo
NA|VP30|KC545393|Bundibugyo_ebolavirus|EboBund_112_2012|NA|2012|Human|Democratic_Republic_of_the_Congo
I am trying to print this characters from each line:
polymerase|KC545393
VP24|KC545393
VP30|KC545393
How can I do this?
I tried this code:
for character in line:
if character=="|":
print line[1:i.index(j)]
Use str.split() to split each line by the '|' character; you can limit the splitting because you only need the first 3 columns:
elems = line.split('|', 3)
print '|'.join(elems[1:3])
The print line then takes the elements at index 1 and 2 and joins them together again using the '|' character to produce your desired output.
Demo:
>>> lines = '''\
... NA|polymerase|KC545393|Bundibugyo_ebolavirus|EboBund_112_2012|NA|2012|Human|Democratic_Republic_of_the_Congo
... NA|VP24|KC545393|Bundibugyo_ebolavirus|EboBund_112_2012|NA|2012|Human|Democratic_Republic_of_the_Congo
... NA|VP30|KC545393|Bundibugyo_ebolavirus|EboBund_112_2012|NA|2012|Human|Democratic_Republic_of_the_Congo
... '''.splitlines(True)
>>> for line in lines:
... elems = line.split('|', 3)
... print '|'.join(elems[1:3])
...
polymerase|KC545393
VP24|KC545393
VP30|KC545393
Assuming you know that each line has at least two separators, you can use:
>>> s = 'this|is|a|string'
>>> s
'this|is|a|string'
>>> s[:s.find('|',s.find('|')+1)]
'this|is'
This finds the first | starting at the character position beyond the first | (i.e., it finds the second |) then gives you the substring up but not including to that point.
If it may not have two separators, you just have to be more careful:
s = 'blah blah'
result = s
if s.find('|') >= 0:
if s.find('|',s.find('|')+1) >= 0:
result = s[:s.find('|',s.find('|')+1)]
If that's the case, you'll probably definitely want it in a more general purpose function, something like:
def substringUpToNthChar(str,n,ch):
if n < 1: return ""
pos = -1
while n > 0:
pos = str.find(ch,pos+1)
if pos < 0: return str
n -= 1
return str[:pos]
This will correctly handle the case where there's fewer separators than desired and will also handle (relatively elegantly) getting more than the first two fields.

Resources