So I have a long list of strings in the same format, and I want to find the last "." character in each one, and replace it with ". - ". I've tried using rfind, but I can't seem to utilize it properly to do this.
Asked
Active
Viewed 1.4e+01k times
108
-
Possible duplicate of [rreplace - How to replace the last occurrence of an expression in a string?](https://stackoverflow.com/questions/2556108/rreplace-how-to-replace-the-last-occurrence-of-an-expression-in-a-string) – Graham Jun 09 '18 at 13:57
7 Answers
168
This should do it
old_string = "this is going to have a full stop. some written sstuff!"
k = old_string.rfind(".")
new_string = old_string[:k] + ". - " + old_string[k+1:]

Aditya Sihag
- 5,057
- 4
- 32
- 43
-
1Thanks so much man. Going to have to study that for a minute... this is utilizing slices, right? – Adam Magyar Jan 24 '13 at 07:41
-
@AdamMagyar yes, container[a:b] slices from a up to b-1 index of the container. If 'a' is omitted, then it defaults to 0; if 'b' is omitted it defaults to len(container). The plus operator just concatenates. The rfind function as you pointed out returns the index around which the replacement operation should take place. – Aditya Sihag Jan 24 '13 at 07:44
28
To replace from the right:
def replace_right(source, target, replacement, replacements=None):
return replacement.join(source.rsplit(target, replacements))
In use:
>>> replace_right("asd.asd.asd.", ".", ". -", 1)
'asd.asd.asd. -'

Gareth Latty
- 86,389
- 17
- 178
- 183

Varinder Singh
- 1,570
- 1
- 11
- 25
-
1I definitely like this solution but having `replacements=None` parameter seems like an error to me because if the parameter is omitted the function will give an error (tried in Python 2.7). I would suggest either remove the default value, set it to -1 (for unlimited replacements) or better make it `replacements=1` (which I think should be the default behaviour for this particular function according to what the OP wants). According to the [docs](https://docs.python.org/2/library/stdtypes.html#str.split) this parameter is optional, but it must be an int if given. – remarkov May 14 '16 at 08:05
-
In case anyone wants a one-liner for this: `". -".join("asd.asd.asd.".rsplit(".", 1))`. All you're doing is performing a string split from the right side for 1 occurrence and joining the string again using the replacement. – bsplosion Apr 23 '20 at 22:16
15
I would use a regex:
import re
new_list = [re.sub(r"\.(?=[^.]*$)", r". - ", s) for s in old_list]

Tim Pietzcker
- 328,213
- 58
- 503
- 561
-
2This is the only answer that works if there's no dot at all. I'd use a lookahead though: `\.(?=[^.]*$)` – georg Jan 24 '13 at 10:18
6
A one liner would be :
str=str[::-1].replace(".",".-",1)[::-1]

magor
- 670
- 10
- 14
-
1**This is wrong**. You're reversing the string, replacing it and then reversing it back. You're doing `.replace` on a reversed string. Both of the strings passed to `replace` have to be reversed too. Otherwise when you reverse the string a second time the letters you just inserted will be backwards. You can only use this if you're replacing one letter with one letter, and even then I wouldn't put this in your code incase someone has to change it in the future and starts wondering why a word is written sdrawkcab. – Boris Verkhovskiy Jan 13 '19 at 18:08
1
You can use the function below which replaces the first occurrence of the word from right.
def replace_from_right(text: str, original_text: str, new_text: str) -> str:
""" Replace first occurrence of original_text by new_text. """
return text[::-1].replace(original_text[::-1], new_text[::-1], 1)[::-1]

bambuste
- 147
- 2
- 9
0
a = "A long string with a . in the middle ending with ."
# if you want to find the index of the last occurrence of any string, In our case we #will find the index of the last occurrence of with
index = a.rfind("with")
# the result will be 44, as index starts from 0.

Arpan Saini
- 4,623
- 1
- 42
- 50
-1
Naïve approach:
a = "A long string with a . in the middle ending with ."
fchar = '.'
rchar = '. -'
a[::-1].replace(fchar, rchar[::-1], 1)[::-1]
Out[2]: 'A long string with a . in the middle ending with . -'
Aditya Sihag's answer with a single rfind
:
pos = a.rfind('.')
a[:pos] + '. -' + a[pos+1:]

Alex L
- 8,748
- 5
- 49
- 75
-
This reverses the replacement string too. Other than that, it's a repeat of root's answer, and, as I say there, pretty inefficient. – Gareth Latty Jan 24 '13 at 07:39
-
-
-
Just expecting the user to reverse the string literal by hand isn't a great idea - it is prone to mistakes and unclear. – Gareth Latty Jan 24 '13 at 07:50
-
@Lattyware Agreed. I've made it a var. (I realise it's an inefficient method, and is not suitable in all cases - your `replace_right` is much nicer) – Alex L Jan 24 '13 at 07:54
-
It's not mine - I just edited the example on Varinder Singh's answer - my first thought was actually this method as well. – Gareth Latty Jan 24 '13 at 07:57