给出字符串:
X做了一些事。 X觉得很好,所以X回家了。
我想用Y替换所有出现的X
,但第一个出现,用Y替换,使得输出字符串看起来像:
X做了一些事。 Y觉得很好,所以Y回家了。
我尝试了许多正则表达式模式(基于https://vi.stackexchange.com/questions/10905/substitution-how-to-ignore-the-nth-first-occurrences-of-a-pattern),但未能通过Python实现。
答案 0 :(得分:7)
str.partition
将字符串分为定界符之前的部分,定界符本身和之后的部分,如果不存在定界符,则将字符串和两个空字符串分开。归结为:
s = 'X did something. X found it to be good, and so X went home.'
before, first, after = s.partition('X')
result = before + first + after.replace('X', 'Y')
答案 1 :(得分:6)
您冷酷地使用re.sub使用函数的事实:
import re
def repl(match, count=[0]):
x, = count
count[0] += 1
if x > 0:
return 'Y'
return 'X'
print(re.sub('X', repl, 'X did something. X found it to be good, and so X went home.'))
输出
X did something. Y found it to be good, and so Y went home.
想法是使用保留可见X
计数的函数,然后在计数大于1时将其替换。
答案 2 :(得分:3)
另一种选择是找到第一个并且仅在替换所有X
次出现之后。
最后,将句子的开头和开头连在一起
st = 'X did something. X found it to be good, and so X went home.'
first_found = st.find('X')
print (st[:first_found + 1] + st[first_found + 1:].replace('X', 'Y'))
# X did something. Y found it to be good, and so Y went home.
答案 3 :(得分:2)
这是没有正则表达式的低技术解决方案。 :)
>>> s = 'X did something. X found it to be good, and so X went home'
>>> s = s.replace('X', 'Y').replace('Y', 'X', 1)
>>> s
>>> 'X did something. Y found it to be good, and so Y went home'
原始字符串中是否存在'Y'
的解决方案:
def replace_tail(s, target, replacement):
try:
pos = s.index(target)
except ValueError:
return s
pos += len(target)
head = s[:pos]
tail = s[pos:]
return head + tail.replace(target, replacement)
演示:
>>> s = 'Today YYY and XXX did something. XXX found it to be good, and so XXX went home without YYY.'
>>> replace_tail(s, 'XXX', 'YYY')
>>> 'Today YYY and XXX did something. YYY found it to be good, and so YYY went home without YYY.'
答案 4 :(得分:1)
在找到其余字符串的第一个匹配项之后,迭代地应用正则表达式。或者,如果可能,仅使用replace
。
答案 5 :(得分:1)
我们可以使用 slicing 生成两个字符串:第一个字符串(直到(包括)第一个元素),以及下一个包含其余元素的切片。然后,我们可以在该部分上应用替换部分,并将它们合并回去:
def replace_but_first(text, search, replace):
try:
idx = text.index(search) + len(search)
return text[:idx] + text[idx:].replace(search, replace)
except ValueError: # we did not found a single match
return text
例如:
>>> replace_but_first('X did something. X found it to be good, and so X went home.', 'X', 'Y')
'X did something. Y found it to be good, and so Y went home.'
答案 6 :(得分:0)
如果您仍然对使用正则表达式操作感兴趣,可以使用re.finditer()
。这将返回一个迭代器,该迭代器将为找到的每个匹配案例生成$this->widget('zii.widgets.jui.CJuiDatePicker',array(
'name'=>'date_from',
'id' => 'date_from',
//'value'=> date('d/m/Y',strtotime($date_from)),
'options'=>array(
'dateFormat' =>'dd/mm/yy',
'altFormat' =>'dd/mm/yy',
'changeMonth' => true,
'changeYear' => true,
'showAnim'=>'slide',
'showButtonPanel'=>true,
),
'language' => 'en-GB',
'htmlOptions'=>array(
'class'=>'form-control'
),
));
个实例。通过将迭代器转换为列表,可以索引到MatchObject
实例中。在下面的函数中,MatchObject
表示跳过第一场比赛。
[1:]
运行:
def replace_rest(my_string, replacement):
for match in list(re.finditer(r'(X)', my_string))[1:]:
my_string = my_string[0:match.start()] + replacement + my_string[match.end():]
return my_string
输出:
>>> my_string = "Person X did something. X found it to be good, and so Y went home."
旁注:这对于忽略模式的第n个出现也很有用。