简体   繁体   中英

Using asterisk character (*) as joker in python string replacement?

I am a beginner in python an am currently struggling with something:

I want to make a couple of changes in a single string. Is it possible to use a single asterisk sign (*), as a replacement-joker for a couple of characters? For example I have a string:

string1 = "The new year is about to become an old year"

And I want to use this pattern for finding:

find:
*year*year*

replace it with:
*century*one*

Which will result in:

string1 = "The new century is about to become an old one"

Meaning "*" character will replace all those characters between, and before the "year" and "year" words. Is that possible?

You don't need asterisks. Just use

import re
string1 = "The new year is about to become an old year"
new_string = re.sub(r"(?P<y>year)(.*)(?P=y)", r"century\2one", string1)

Or more concisely:

new_string = re.sub(r"(year)(.*)\1", r"century\2one", string1)

One pass, using regular expressions. Explanation: each parentheses of the first argument defines one capturing group. The first is named "y" (with ?P ) and matches the literal year ; the second matches any number( * ) of any character ( . ); the third matches the named group "y" defined by the first group (in our case, "year"). The second argument replaces the first matched group with century , and the third group with one . Notice that in Python, we start counting from zero .

Kudos to @JonhY for the pointers in the comments below, and also m.buettner . My heros!

It seems to me you haven't heard of regular expressions (or regex ) yet. Regex is a very powerful mini language that is used to match text. Python has a very good implementation of regex. Have a look at:

Tutorial at Regex One

Python Documentation on Regex

It will be worth your while to look into regular expressions . In your case, the main things you need to know are that . matches any single character, .* matches zero or more of any character, that parentheses are used for grouping, and backslash followed by a number form a backreference (of an existing group).

So, to match year , followed by arbitrary stuff, followed by year again, use year.*year .

Now, to substitute, use the grouping and backreference:

import re
string2 = re.sub('year(.*)year', r'century\1one', string1)

Effective use of regular expressions is definitely not obvious to most beginners. For some suggestions on gentler introductions, see this question:

https://stackoverflow.com/questions/2717856/any-good-and-gentle-python-regexp-tutorials-out-there

string1 = "The new year is about to become an old year"
find = '*year*year*'
replace = '*century*one*'

for  f,r in zip(find.strip('*').split('*'), replace.strip('*').split('*')):
    string1 = string1.replace(f, r, 1)

Output:

The new century is about to become an old one

This is a sample implementation that does not do any error checking.

>>> def custom_replace(s, find_s, replace_s):
...     terms = find_s.split('*')[1:-1]
...     replacements = replace_s.split('*')[1:-1]
...     for term, replacement in zip(terms, replacements):
...       s = s.replace(term, replacement, 1)
...     return s
... 
>>> string1 = "The new year is about to become an old year"
>>> print custom_replace(string1, "*year*year*", "*century*one*")
The new century is about to become an old one
>>> 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM