有没有办法轻松交换字符串中的两个字符?
Is there any way to swap two characters in a string easily?
例如
输入:
text = 'wish you “happy” every (day)'
预期输出:
text = 'wish you (happy) every “day”'
我想在未知文本中的所有地方用引号交换括号。
我正在做学校作业,但不允许我使用列表!!!
由于字符串是不可变的,所以我不确定该怎么做。请帮忙!
这是一个使用 string.replace() 的愚蠢答案:
text = 'wish you “happy” every (day)'
text = text\
.replace('”', '*')\
.replace('“', "^")\
.replace("(", '“')\
.replace(")", '”')\
.replace("*", ')')\
.replace("^", '(')
这里是一个严肃的答案:
由于您有一个要替换的字符列表,因此构建一个字典,其中包含应该与另一个字符交换的字符,然后遍历该字符串并创建一个新字符串,其中包含带有替换字母的原始字符串。这样,您可以根据需要在 switch 字典中拥有任意数量的字符串,并且它无需修改即可工作。考虑到更大的规模,您可能想要做一些事情,例如将此字典存储在其他地方,例如,如果您根据从界面或 Web 应用程序获得的用户输入创建它。将您正在做什么和如何做的规范分开通常是好的,因为一个可以被视为数据(要交换哪些字符)而另一个是逻辑(实际上交换它们)。
text = 'wish you “happy” every (day)'
newtext = ''
switch = {
'“': '(',
'”': ')',
'(': '“',
')': '”',
}
for letter in text:
if letter in switch: letter = switch[letter]
newtext += letter
我采用迭代方法的原因是因为我们正在交换字符,所以如果您同时替换每个字符的所有实例,除非您包括中间步骤,否则一旦您交换下一个字符,字符就会被交换回去例如我愚蠢的答案中的 *
或另一个答案中的 ###
,这会带来冲突的可能性(如果您的文本已经包含 ###
或 *
,它将被错误地替换).
字符串的不变性是您必须创建 newtext
字符串而不是在我迭代时替换原始字符串中的字符的原因。
您需要的是正则表达式替换。此外,该组应保留。
注意:我不得不使用 3 个替换,因为有一个交换。
a = 'wish you "happy" every (day)'
b = re.sub(r'"(\w+)"', r'######', a)
// replaces words inside double quotes to words inside ###
// b = 'wish you ###happy### every (day)'
c = re.sub(r'\((\w+)\)', r'""', b)
// replaces words inside paranthesis to words inside double quotes
// c = 'wish you ###happy### every "day"'
d = re.sub(r'###(\w+)###', r'()', c)
// replaces the words inside ### to paranthesis
// d = 'wish you (happy) every "day"'
中间替换通常是易受攻击的,因为文本可能包含中间表示:###...###
在 Roopak A Nelliat 的回答中,*
和 ^
在 Ryan 的 "silly" 中(编辑:正如 Ryan 在下面更严肃的文字中所指出的)。
这是一个不经过中间替换的正则表达式解决方案:
text = 'wish you "happy" every (day)'
def replacer(match):
quote, content = match.groups()
if quote:
return f'({content})'
else:
return f'"{content}"'
re.sub(r'(?:(")|\()(.*?)(?(1)"|\))', replacer, text)
# => 'wish you (happy) every "day"'
正则表达式将匹配起始分隔符("
或 (
),然后是内容,最后匹配一个分隔符(即,如果起始分隔符是 "
,则 "
,如果不是则 )
)。然后 replacer 函数用另一组定界符构造一个替换。
例如 输入:
text = 'wish you “happy” every (day)'
预期输出:
text = 'wish you (happy) every “day”'
我想在未知文本中的所有地方用引号交换括号。 我正在做学校作业,但不允许我使用列表!!! 由于字符串是不可变的,所以我不确定该怎么做。请帮忙!
这是一个使用 string.replace() 的愚蠢答案:
text = 'wish you “happy” every (day)'
text = text\
.replace('”', '*')\
.replace('“', "^")\
.replace("(", '“')\
.replace(")", '”')\
.replace("*", ')')\
.replace("^", '(')
这里是一个严肃的答案:
由于您有一个要替换的字符列表,因此构建一个字典,其中包含应该与另一个字符交换的字符,然后遍历该字符串并创建一个新字符串,其中包含带有替换字母的原始字符串。这样,您可以根据需要在 switch 字典中拥有任意数量的字符串,并且它无需修改即可工作。考虑到更大的规模,您可能想要做一些事情,例如将此字典存储在其他地方,例如,如果您根据从界面或 Web 应用程序获得的用户输入创建它。将您正在做什么和如何做的规范分开通常是好的,因为一个可以被视为数据(要交换哪些字符)而另一个是逻辑(实际上交换它们)。
text = 'wish you “happy” every (day)'
newtext = ''
switch = {
'“': '(',
'”': ')',
'(': '“',
')': '”',
}
for letter in text:
if letter in switch: letter = switch[letter]
newtext += letter
我采用迭代方法的原因是因为我们正在交换字符,所以如果您同时替换每个字符的所有实例,除非您包括中间步骤,否则一旦您交换下一个字符,字符就会被交换回去例如我愚蠢的答案中的 *
或另一个答案中的 ###
,这会带来冲突的可能性(如果您的文本已经包含 ###
或 *
,它将被错误地替换).
字符串的不变性是您必须创建 newtext
字符串而不是在我迭代时替换原始字符串中的字符的原因。
您需要的是正则表达式替换。此外,该组应保留。
注意:我不得不使用 3 个替换,因为有一个交换。
a = 'wish you "happy" every (day)'
b = re.sub(r'"(\w+)"', r'######', a)
// replaces words inside double quotes to words inside ###
// b = 'wish you ###happy### every (day)'
c = re.sub(r'\((\w+)\)', r'""', b)
// replaces words inside paranthesis to words inside double quotes
// c = 'wish you ###happy### every "day"'
d = re.sub(r'###(\w+)###', r'()', c)
// replaces the words inside ### to paranthesis
// d = 'wish you (happy) every "day"'
中间替换通常是易受攻击的,因为文本可能包含中间表示:###...###
在 Roopak A Nelliat 的回答中,*
和 ^
在 Ryan 的 "silly" 中(编辑:正如 Ryan 在下面更严肃的文字中所指出的)。
这是一个不经过中间替换的正则表达式解决方案:
text = 'wish you "happy" every (day)'
def replacer(match):
quote, content = match.groups()
if quote:
return f'({content})'
else:
return f'"{content}"'
re.sub(r'(?:(")|\()(.*?)(?(1)"|\))', replacer, text)
# => 'wish you (happy) every "day"'
正则表达式将匹配起始分隔符("
或 (
),然后是内容,最后匹配一个分隔符(即,如果起始分隔符是 "
,则 "
,如果不是则 )
)。然后 replacer 函数用另一组定界符构造一个替换。