Reputation: 666
Let's say I have the following collection of strings inside a list:
list_of_strings = [ "data_1 = 3,", "re = 3,", "item = 5"]
Now I want to find the string "item" and replace the following number 5 with f.e. 10 making the whole line:
item = 10
using regex I have no problem finding "item", but have no idea how I can point to the number and change it.
Clarification:
The ultimate goal is to have a function that searches for a given string inside a list of strings and exchange the value associated with the string:
match_str = item_x
change_value = 10
list = ["string1","string2","string5","item_x = 3", ...]
change_parameter(match_str,change_value,list)
Preferably change_value can be a string or a float
Upvotes: 0
Views: 730
Reputation: 2693
You don't just need to find the word item
, you can also include the following number in the regex, and replace the whole thing with item = 10
.
\s+
in regex matches for one or more white-space characters, if you want spaces to be optional, you can use \s*
, which matches for zero or more white-space characters.
>>> l = ['data_1 = 3', 're = 3', 'item = 5']
>>> import re
>>> r = re.compile(r'item\s*=\s*\d+')
>>> updated_l = [r.sub('item = 10', s) if r.match(s) else s for s in l]
>>> print(updated_l)
['data_1 = 3', 're = 3', 'item = 10']
Edit:
To comply your latest changes, i.e. to make it generic. Let's write up a function which searches for some value and replaces it's value. I'll be using the same approach which I currently have.
def change_parameter(match_str, change_value, list1):
# First, let's create a regex for it, and compile it
r = re.compile(r'{0}\s*=\s*\d+'.format(match_str))
# Find, and replace the matching string's value
updated_l = [r.sub('{0} = {1}'.format(match_str, change_value), s) if r.match(s) else s for s in list1]
return updated_l
Now, let's test this change_parameter
method for different values:
>>> l = ['data_1 = 3', 're = 3', 'item = 5']
>>> change_parameter('item', 10, l)
['data_1 = 3', 're = 3', 'item = 10']
>>> change_parameter('re', 7, l)
['data_1 = 3', 're = 7', 'item = 5']
And for string and float replacements:
>>> change_parameter('re', 7.1, l)
['data_1 = 3', 're = 7.1', 'item = 5']
>>> change_parameter('data_1', '11', l)
['data_1 = 11', 're = 3', 'item = 5']
Upvotes: 3
Reputation: 25023
Assuming that you want to modify your list in place, so that I can develop from an angle unexplored in other answers, we can proceed using an enumeration of the list elements, looping so that, for all the list elements that start with "item"
, we use re.sub
to change the number (and only the number... and not only 5
but every digit sequence...)
for i, element in enumerate(data):
if element.startswith("item"):
data[i] = re.sub("[0-9]+", "10", element)
P.S. if an element starts with item
and doesn't contain a number, the element is left unchanged by the substitution.
Upvotes: 0
Reputation: 23306
A better, more general solution to what you're trying to do is to use the documented ability of re.sub
to accept a substitution function (given a Match object you can return the string to substitute). You can write this in such a way that it will work for any key = val
string. There are many ways to do this of course but you mentioned regular expressions so this is one way...
from functools import partial
import re
def subst_val(newval, m):
return '{} = {}'.format(m.group('key'), newval)
keyval_re = re.compile(r'(?P<key>[^= ]+)\s*=\s*(?P<val>.+)')
Where you might adjust the regex depending on the exact syntax for your needs. Then use it like:
keyval_re.sub(partial(subst_val, 10)), 'item = 5')
which will return 'item = 10'. This will work the same regardless what the LHS key is. Honestly there are simpler ways to do this but this one is reasonably robust.
Upvotes: 1
Reputation: 1740
I'm not sure what you mean by collection of strings (In your example there are defined variables. But maybe this will work in your case) Use replace()
function:
string.replace(s, old, new[, maxreplace])
Return a copy of string s with all occurrences of substring old replaced by new. If the optional argument maxreplace is given, the first maxreplace occurrences are replaced.
string = """
data_1 = 3,
re = 3,
item = 5.
"""
new_str = string.replace("item = 5", "item = 10")
print(new_str)
Output:
data_1 = 3,
re = 3,
item = 10.
Upvotes: -1