Replace non-numeric characters in string - python-3.x

I would like to know how to replace non-numeric characters in a single string with different random integers.
I have tried the following:
text = '1$1#387'
rec_1 = re.sub("\D+",str(random.randint(0,9)),text)
It then produced:
output: 1717387
As you can see, the non-numeric characters have been replaced by the same integer. I would like each non-numeric character to be replaced by a different integer. For example:
desired output: 1714387
Please assist.

Use a function as the replacement value:
def replacement(match):
return str(random.randint(0, 9))
text = '1$1#387'
rec_1 = re.sub(r"\D", replacement, text)
rec_1 is now "1011387", or "1511387", ...

That's because the randint function is called only 1 time.
You can use a lambda to get a new randint each time:
rec_1 = re.sub("\D+", lambda x: str(random.randint(0, 9)), text)

Related

Python split currency string into currency code and amount

I am trying to split R15.49 to (R, 15.49) or
ZAR15.49 to (ZAR, 15.49)
I have tried one of the solutions here and implememted the function below:
def splitCurrency(string):
match = re.search(r'([\D]+)([\d,]+)', string)
output = (match.group(1), match.group(2).replace(',',''))
return output
But I am getting (R, 15) or (ZAR, 15). and its ignoring the digits after the decimal place
If you want to fish out these values from a larger text, then use re.findall:
inp = "R15.49 or ZAR15.49"
matches = re.findall(r'\b([A-Z]+)(\d+(?:\.\d+)?)\b', inp)
print(matches)
This prints:
[('R', '15.49'), ('ZAR', '15.49')]

String replacement in python is replacing the entire string

When I do the string replacement I am getting an error. For example: my string is my_string = '15:15'. I want to replace 15 which is after the colon to 30. For example I need '15:30'. When I try to do the string replace it's working fine for all other values for example, '09:15', '09:20'.
I have tried:
my_string = '15:15'
my_new_string = my_string.replace(my_string[-2:], '30')
my_string = '15:15'
my_new_string = my_string.replace(my_string[-2:], '30')
What I am expecting is 15:30 but my actual output is 30:30
my_new_string = my_string.replace(my_string[-2:],'30') gets you 30:30, because you are replacing all occurrences of 15 -> 15:15 will become 30:30.
You could use str.split and str.format to get your new string:
my_string = '15:15'
my_new_string = '{}:{}'.format(my_string.split(':')[0], '30')
print(my_new_string)
Prints:
15:30
That is the expected behavior. Look at what the arguments for str.replace() mean:
replace(...)
S.replace(old, new[, count]) -> string
Return a copy of string S with all occurrences of substring
old replaced by new. If the optional argument count is
given, only the first count occurrences are replaced.
It does not replace a substring, rather all occurrences of what you pass as the first parameter.
By calling my_string.replace(my_string[-2:], '30') you're essentially calling '15:15'.replace('15', '30') -- which will replace all occurrences of "15" by "30" so you'll end up with '30:30'.
If you want to replace the last two characters, reverse your logic: keep everything up to the last two characters and then add the '30' string you want at the end:
my_new_string = my_string[:-2] + '30'
When you use my_string[-2:] you are getting the string '15:'. Then when you substitute the function string.replace replaces all occurrences of 15: with 3, giving you 3030.
Instead, you can use my_string[2:] to get the string ':15' and replace it with ':30'. If you don't include the colon, then you will replace both occurrences of 15 and get '30:30'
my_new_string = my_string.replace(my_string[:-2], ':30')

Get digits at end of string in a pythonic way

I'm using python 3.x. I'm trying to get the (int) number at the end of a string with format
string_example_1 = l-45-98-567-567-12
string_example_2 = s-89-657
or in general, a single lowercase letter followed by a number of integers separated by '-'. What I need is to get the last number (12 and 657 in these cases). I have archived this with the function
def ending(the_string):
out = ''
while the_string[-1].isdigit():
out = the_string[-1] + out
the_string = the_string[:-1]
return out
but I'm sure there must be a more pythonic way to do this. In a previous instance I check manually that the string starts the way I like by doing something like
if st[0].isalpha() and st[1]=='-' and st[2].isdigit():
statement...
I would just split the string on -, take the last of the splits and convert it to an integer.
string_example_1 = "l-45-98-567-567-12"
string_example_2 = "s-89-657"
def last_number(s):
return int(s.split("-")[-1])
print(last_number(string_example_1))
# 12
print(last_number(string_example_2))
# 657
Without regular expressions, you could reverse the string, take elements from the string while they're still numbers, and then reverse the result. In Python:
from itertools import takewhile
def extract_final_digits(s):
return int(''.join(reversed(list(takewhile(lambda c: c.isdigit(), reversed(s))))))
But the simplest is to just split on a delimiter and take the final element in the split list.

Split by the delimiter that comes first, Python

I have some unpredictable log lines that I'm trying to split.
The one thing I can predict is that the first field always ends with either a . or a :.
Is there any way I can automatically split the string at whichever delimiter comes first?
Look at the index of the . and : characters in the string using the index() function.
Here’s a simple implementation:
def index_default(line, char):
"""Returns the index of a character in a line, or the length of the string
if the character does not appear.
"""
try:
retval = line.index(char)
except ValueError:
retval = len(line)
return retval
def split_log_line(line):
"""Splits a line at either a period or a colon, depending on which appears
first in the line.
"""
if index_default(line, ".") < index_default(line, ":"):
return line.split(".")
else:
return line.split(":")
I wrapped the index() function in an index_default() function because if the line doesn’t contain a character, index() throws a ValueError, and I wasn’t sure if every line in your log would contain both a period and a colon.
And then here’s a quick example:
mylines = [
"line1.split at the dot",
"line2:split at the colon",
"line3:a colon preceded. by a dot",
"line4-neither a colon nor a dot"
]
for line in mylines:
print split_log_line(line)
which returns
['line1', 'split at the dot']
['line2', 'split at the colon']
['line3', 'a colon preceded. by a dot']
['line4-neither a colon nor a dot']
Check the indexes for both both characters, then use the lowest index to split your string.

How to change a dictionary in to a string

def dict_to_str(d):
'''(dict) -> str
Returns a string containing each key and value in d. Keys and values
are separated by a space. Each key-value pair is separated by a
comma.
>>> dict_to_str({3:4, 5:6})
'3 4, 5 6'
'''
The following is in Python.
exDict = {1:3, 2:4}
# This will give you a string that looks like "{1: 3, 2: 4}".
stringDict = str(exDict)
At this point you have a string of the dict. What you need to do now is replace the curly brackets and colon with an empty space. This should give you the form you want.
for char in stringDict:
if char in "{}:":
stringDict = stringDict.replace(char, "")
That should do the trick.

Resources