Update last character of string with a value - python

I have two strings:
input = "12.34.45.362"
output = "2"
I want to be able to replace the 362 in input by 2 from output.
Thus the final result should be 12.34.45.2. I am unsure on how to do it. Any help is appreciated.

You can use a simple regex for this:
import re
input_ = "12.34.45.362"
output = "2"
input_ = re.sub(r"\.\d+$", f".{output}", input_)
print(input_)
Output:
12.34.45.2
Notice that I also changed input to input_, so we're not shadowing the built-in input() function.
Can also use a more simple, but little bit less robust pattern, which doesn't take the period into account at all, and just replaces all the digits from the end:
import re
input_ = "12.34.45.362"
output = "2"
input_ = re.sub(r"\d+$", output, input_)
print(input_)
Output:
12.34.45.2

Just in case you want to do this for any string of form X.Y.Z.W where X, Y, Z, and W may be of non-constant length:
new_result = ".".join(your_input.split(".")[:-1]) + "." + output
s.join will join a collection together to a string using the string s between each element. s.split will turn a string into a list which each element between the given character .. Slicing the list (l[:-1]) will give you all but the last element, and finally string concatenation (if you are sure output is str) will give you your result.
Breaking it down step-by-step:
your_input = "12.34.45.362"
your_input.split(".") # == ["12", "34", "45", "362"]
your_input.split(".")[:-1] # == ["12", "34", "45"]
".".join(your_input.split(".")[:-1]) # == "12.34.45"
".".join(your_input.split(".")[:-1]) + "." + output # == "12.34.45.2"

If you are trying to split int the lat . just do a right split get everything and do a string formatting
i = "12.34.45.362"
r = "{}.2".format(i.rsplit(".",1)[0])
output
'12.34.45.2'

Related

python string split slice and into a list

I have a string for example "streemlocalbbv"
and I have my_function that takes this string and a string that I want to find ("loc") in the original string. And what I want to get returned is this;
my_function("streemlocalbbv", "loc")
output = ["streem","loc","albbv"]
what I did so far is
def find_split(string,find_word):
length = len(string)
find_word_start_index = string.find(find_word)
find_word_end_index = find_word_start_index + len(find_word)
string[find_word_start_index:find_word_end_index]
a = string[0:find_word_start_index]
b = string[find_word_start_index:find_word_end_index]
c = string[find_word_end_index:length]
return [a,b,c]
Trying to find the index of the string I am looking for in the original string, and then split the original string. But from here I am not sure how should I do it.
You can use str.partition which does exactly what you want:
>>> "streemlocalbbv".partition("loc")
('streem', 'loc', 'albbv')
Use the split function:
def find_split(string,find_word):
ends = string.split(find_word)
return [ends[0], find_word, ends[1]]
Use the split, index and insert function to solve this
def my_function(word,split_by):
l = word.split(split_by)
l.insert(l.index(word[:word.find(split_by)])+1,split_by)
return l
print(my_function("streemlocalbbv", "loc"))
#['str', 'eem', 'localbbv']

split string every nth character and append ':'

I've read some switch MAC address table into a file and for some reason the MAC address if formatted as such:
'aabb.eeff.hhii'
This is not what a MAC address should be, it should follow: 'aa:bb:cc:dd:ee:ff'
I've had a look at the top rated suggestions while writing this and found an answer that may fit my needs but it doesn't work
satomacoto's answer
The MACs are in a list, so when I run for loop I can see them all as such:
Current Output
['8424.aa21.4er9','fa2']
['94f1.3002.c43a','fa1']
I just want to append ':' at every 2nd nth character, I can just remove the '.' with a simple replace so don't worry about that
Desired output
['84:24:aa:21:4e:r9','fa2']
['94:f1:30:02:c4:3a','fa1']
My code
info = []
newinfo = []
file = open('switchoutput')
newfile = file.read().split('switch')
macaddtable = newfile[3].split('\\r')
for x in macaddtable:
if '\\n' in x:
x = x.replace('\\n', '')
if carriage in x:
x = x.replace(carriage, '')
if '_#' in x:
x = x.replace('_#', '')
x.split('/r')
info.append(x)
for x in info:
if "Dynamic" in x:
x = x.replace('Dynamic', '')
if 'SVL' in x:
x = x.replace('SVL', '')
newinfo.append(x.split(' '))
for x in newinfo:
for x in x[:1]:
if '.' in x:
x = x.replace('.', '')
print(x)
Borrowing from the solution that you linked, you can achieve this as follows:
macs = [['8424.aa21.4er9','fa2'], ['94f1.3002.c43a','fa1']]
macs_fixed = [(":".join(map(''.join, zip(*[iter(m[0].replace(".", ""))]*2))), m[1]) for m in macs]
Which yields:
[('84:24:aa:21:4e:r9', 'fa2'), ('94:f1:30:02:c4:3a', 'fa1')]
If you like regular expressions:
import re
dotted = '1234.3456.5678'
re.sub('(..)\.?(?!$)', '\\1:', dotted)
# '12:34:34:56:56:78'
The template string looks for two arbitrary characters '(..)' and assigns them to group 1. It then allows for 0 or 1 dots to follow '\.?' and makes sure that at the very end there is no match '(?!$)'. Every match is then replaced with its group 1 plus a colon.
This uses the fact that re.sub operates on nonoverlapping matches.
x = '8424.aa21.4er9'.replace('.','')
print(':'.join(x[y:y+2] for y in range(0, len(x) - 1, 2)))
>> 84:24:aa:21:4e:r9
Just iterate through the string once you've cleaned it, and grab 2 string each time you loop through the string. Using range() third optional argument you can loop through every second elements. Using join() to add the : in between the two elements you are iterating.
You can use re module to achieve your desired output.
import re
s = '8424.aa21.4er9'
s = s.replace('.','')
groups = re.findall(r'([a-zA-Z0-9]{2})', s)
mac = ":".join(groups)
#'84:24:aa:21:4e:r9'
Regex Explanation
[a-zA-Z0-9]: Match any alphabets or number
{2}: Match at most 2 characters.
This way you can get groups of two and then join them on : to achieve your desired mac address format
wrong_mac = '8424.aa21.4er9'
correct_mac = ''.join(wrong_mac.split('.'))
correct_mac = ':'.join(correct_mac[i:i+2] for i in range(0, len(correct_mac), 2))
print(correct_mac)

simple way convert python string to quoted string

i'm new to python and i'm having a select statement like following help_category_id, name, what is the most effective way to convert this string to this:
'help_category_id', 'name'
i've currently done this, which works fine, but is there a nicer and more clean way to do the same:
test_string = 'help_category_id, name'
column_sort_list = []
if test_string is not None:
for col in test_string.split(','):
column = "'{column}'".format(column=col)
column_sort_list.append(column)
column_sort = ','.join(column_sort_list)
print(column_sort)
Simple one liner using looping constructs:
result = ", ".join(["'" + i + "'" for i.strip() in myString.split(",")])
What we are doing here is we are creating a list that contains all substrings of your original string, with the quotes added. Then, using join, we make that list into a comma delimited string.
Deconstructed, the looping construct looks like this:
resultList = []
for i in myString.split(","):
resultList.append("'" + i.strip() + "'")
Note the call to i.strip(), which removes extraneous spaces around each substring.
Note: You can use format syntax to make this code even cleaner:
New syntax:
result = ", ".join(["'{}'".format(i.strip()) for i in myString.split(",")])
Old syntax:
result = ", ".join(["'%s'" % i.strip() for i in myString.split(",")])
it can be achieved by this also.
','.join("'{}'".format(value) for value in map(lambda text: text.strip(), test_string.split(",")))

Replace specific instance in string - Python

I know that the following is how to replace a string with another string i
line.replace(x, y)
But I only want to replace the second instance of x in the line. How do you do that?
Thanks
EDIT
I thought I would be able to ask this question without going into specifics but unfortunately none of the answers worked in my situation. I'm writing into a text file and I'm using the following piece of code to change the file.
with fileinput.FileInput("Player Stats.txt", inplace=True, backup='.bak') as file:
for line in file:
print(line.replace(chosenTeam, teamName), end='')
But if chosenTeam occurs multiple times then all of them are replaced.
How can I replace only the nth instance in this situation.
That's actually a little tricky. First use str.find to get an index beyond the first occurrence. Then slice and apply the replace (with count 1, so as to replace only one occurrence).
>>> x = 'na'
>>> y = 'banana'
>>> pos = y.find(x) + 1
>>> y[:pos] + y[pos:].replace(x, 'other', 1)
'banaother'
Bonus, this is a method to replace "NTH" occurrence in a string
def nth_replace(str,search,repl,index):
split = str.split(search,index+1)
if len(split)<=index+1:
return str
return search.join(split[:-1])+repl+split[-1]
example:
nth_replace("Played a piano a a house", "a", "in", 1) # gives "Played a piano in a house"
You can try this:
import itertools
line = "hello, hi hello how are you hello"
x = "hello"
y = "something"
new_data = line.split(x)
new_data = ''.join(itertools.chain.from_iterable([(x, a) if i != 2 else (y, a) for i, a in enumerate(new_data)]))

Replacing specific symbol in a string in python, LaTeX to HTML without converter

I have a string, w, and I want to replace "$_" with "<sub>" and the first "$" after "$_" with "</sub>". I need to do the same with replacing "$^" with "<sup>" and the "$" after it with "</sup>". I tried w.replace("$_", "<sub>") and w.replace("$", "</sub>"), but I can't get only the first "$" after "$_" to be replaced with "</sub>", only every "$" after it. The same follows for replacing "$^" with "<sup>". How can I call only the "$" directly after the "$_" or "$^" indicators to change and not the rest?
Python code:
w = ["Li$_3$O$^cat$", "Al$_2$O$_3$", "ZnO", "H$_2$O+O$^3$"]
w = str(w)
if '$_' in w:
w = w.replace("$_", "<sub>")
w = w.replace("$", "</sub>")
if '$^' in w:
w = w.replace("$^","<sup>")
w = w.replace("$","</sup>")
print w
Desired output:
['Li< sub >3< /sub >O< sup >cat< /sup >',
'Al< sub >2< /sub >O< sub >3< /sub >',
'ZnO',
'H< sub >2< /sub >O+O< sup >3< /sup >']
With regex, you can replace only the first occurrence using count=1 parameter, with those 2 statements:
w = re.sub(r"\$_","<sub>",w,count=1)
w = re.sub(r"\$","</sub>",w,count=1)
(note the escaping of the $ sign)
Another way is to use str.partition which splits according to left part, separator, right part, and rebuild a string using a new separator:
parts = w.partition("$_")
w = parts[0]+"<sub>"+parts[2]
parts = w.partition("$")
w = parts[0]+"</sub>"+parts[2]
or
w = "<sub>".join(w.partition("$_")[::2])
w = "</sub>".join(w.partition("$")[::2])
If you want to replace all (non-overlapping) instances, you can do something like this:
import re
re.sub(r'\$_([^$]*)\$', r'<sub>\1</sub>', w)
This will find every instance of $_(everything other than $)$ with <sub>(everything other than $)</sub>.
This means if you have something like Li$_3$O$^cat$, it will be converted to Li<sub>3</sub>O$^cat$.
If you also then want to convert $^...$ to <sup>...</sup>, you can apply a similar strategy. A full example that populates the variable result is given below:
import re
w = ["Li$_3$O$^cat$", "Al$_2$O$_3$", "ZnO", "H$_2$O+O$^3$"]
w = str(w)
result = re.sub(r'\$_([^$]*)\$', r'<sub>\1</sub>', w)
result = re.sub(r'\$\^([^$]*)\$', r'<sup>\1</sup>', result)
print result
With the final output being:
['Li<sub>3</sub>O<sup>cat</sup>', 'Al<sub>2</sub>O<sub>3</sub>', 'ZnO', 'H<sub>2</sub>O+O<sup>3</sup>']
That being said, if the full set of substitutions that need to be done are more complex than this, you may want to store the substitution rules in some sort of data structure. For example:
import re
def substitute(rules, input):
"""Return a string with substitution performed on given input
rules -- dict specifying the substitution rules
input -- input string to be substituted
"""
result = input
for k, v in rules.iteritems():
re_str = r'\$' + re.escape(k) + r'([^$]*)\$'
sub_str = r'<%s>\1</%s>' % (v, v)
result = re.sub(re_str, sub_str, result)
return result
rules = {
'_': 'sub',
'^': 'sup'
}
w = ["Li$_3$O$^cat$", "Al$_2$O$_3$", "ZnO", "H$_2$O+O$^3$"]
print substitute(rules, str(w))
Output:
['Li<sub>3</sub>O<sup>cat</sup>', 'Al<sub>2</sub>O<sub>3</sub>', 'ZnO', 'H<sub>2</sub>O+O<sup>3</sup>']
Note that the above solutions do not deal with nested substitutions. These could be handled using more advanced regular expression features, like negative lookahead, or full parsers if needed.
You could try the following which uses a function to decide which replacement to do for each type:
import re
def replace(r):
if r.group(1):
return "<sub>{}</sub>".format(r.group(1))
else:
return "<sup>{}</sup>".format(r.group(2))
w = ["Li$_3$O$^cat$", "Al$_2$O$_3$", "ZnO", "H$_2$O+O$_3$"]
for text in w:
print re.sub(r"\$_(.*?)\$|\$\^(.*?)\$", replace, text)
Giving you:
Li<sub>3</sub>O<sup>cat</sup>
Al<sub>2</sub>O<sub>3</sub>
ZnO
H<sub>2</sub>O+O<sub>3</sub>
Or as a list comprehension:
output = [re.sub(r"\$_(.*?)\$|\$\^(.*?)\$", replace, t) for t in w]

Categories