【问题标题】:How to replace character ' " ' randomly repeated in a string with alternating characters ' “ ' and ' ” ' (python)?如何用交替字符'“'和'”'(python)替换字符串中随机重复的字符'"'?
【发布时间】:2019-10-25 16:54:08
【问题描述】:

我试图用一组弯曲的开引号和闭引号(“和”)替换给定字符串中的任何普通直引号(“)。这意味着第一个、第三个等“将被替换为”,并且第二个,第四个等“将被替换为”。

我已经尝试找到第一个引号的索引,创建一个拼接到它,并将该拼接中的所有“”替换为“。我通过从这个新引号索引+1到末尾创建一个拼接来遵循这一点并将所有“替换为”。问题是,我不能确定提供的字符串中 "s 的长度或数量,因此需要找到一种方法来循环这样的某种系统。

这仅适用于正确转换带有 2 个引号的字符串:

def convert_quotes(text):
    '''(str) -> str
    Convert the straight quotation mark into open/close quotations.
    >>> convert_quotes('"Hello"')
    '“Hello”'
    >>> convert_quotes('"Hi" and "Hello"')
    '“Hi” and “Hello”'
    >>> convert_quotes('"')
    '“'
    >>> convert_quotes('"""')
    '“”“'
    >>> convert_quotes('" "o" "i" "')
    '“ ”o“ ”i“ ”'
    '''
    find=text.find('"')
    if find != -1:
        for i in text:
            #first convert first found " to “
            text1 = text[:find+1]
            replace1=text1.replace('"','“')
            text2 = text[find+1:]
            replace2=text2.replace('"','”')
            text=replace1+replace2
            return text

从我的文档字符串中可以看出,'"Hello" 应该变成“Hello”,但是 '" "o" "i" "' 应该变成“ ”o“ ”i“ ”。

【问题讨论】:

  • 你也许可以遍历你的字符串并将所有出现的 " 的索引存储在一个列表中,然后用 " 替换所有偶数索引,用 " 替换奇数索引?
  • 这对我来说是最理想的方式,因为我在技术上还没有学习 import re 并且能够使用 enumerate?我的问题是,从技术上讲,如果打开它们,它们并不都有偶数索引,如果关闭则它们是奇数索引,反之亦然。除非我错过了什么?
  • 为了问题的缘故,我会用() 在较小的屏幕上替换quits,很难看出区别。
  • @sarahsss,你可以先找到 " 的索引并将它们存储在一个列表中。所以你会有类似 index = [12, 17, 29, 35] 的东西。然后你可以遍历此索引列表带有 for 循环(类似于... for i in xrange(len(indexes)) 并检查当前迭代是偶数还是奇数(如果 i % 2 == 0 -> 偶数)。如果偶数.. . 你可以用“替换那个索引,如果奇怪,用”替换。这样更有意义吗?

标签: python python-3.x string loops


【解决方案1】:

您可能希望收集所有带引号的位置,然后相应地更改字符。这需要一个中间字符列表(下面的s_list):

import re

s = '"Hi" and "Hello"'
s_list = list(s)

quote_position = [p.start() for p in re.finditer('"', s)]

for po, pc in zip(quote_position[::2], quote_position[1::2]):
    s_list[po] = '“'
    s_list[pc] = '”'

s = "".join(s_list)

【讨论】:

  • 您可以添加注释,该列表将字符串 s 转换为其字母列表。当然,python 是做什么的,但也许不是每个人都知道。您也可以删除 import re
  • 如果您有奇数个引号,这可能不起作用。原始问题显示(如果我理解正确)一个带有奇数双引号的情况。
【解决方案2】:

您可以使用 re.sub 功能。 我将使用括号以提高可读性,只需将它们替换为您的引号即可。

import re

s = """
sdffsd"fsdfsdfdsf fdsf<s" fgdgdfgdf " gfdgdfgd" gdfgdfgdf"
bla re bla
dfsfds " fdsfsdf " fsdfsd "
and the final odd " is here
"""

def func(match): # function for to be called for each sub() step
    return("(" + match.group()[1:-1] + ")")

rex  = re.compile(r'"[^"]*"') # regular expression for a quoted string.

result = rex.sub(func, s) # substitute each match in s with func(match)
result = result.replace('"', '(')  # take care of last remaining " if existing
print(result)

输出将是:

sdffsd(fsdfsdfdsf fdsf<s) fgdgdfgdf ( gfdgdfgd) gdfgdfgdf(
bla re bla
dfsfds ) fdsfsdf ( fsdfsd )
and the final odd ( is here

不使用 re 模块的第二种解决方案:

s = """
sdffsd"fsdfsdfdsf fdsf<s" fgdgdfgdf " gfdgdfgd" gdfgdfgdf"
bla re bla
dfsfds " fdsfsdf " fsdfsd "
and the final odd " is here
"""

while True:
    if not '"' in s:
        break
    s = s.replace('"', '(', 1)
    s = s.replace('"', ')', 1)

print(s)

我没有努力提高效率。 重点是简单。

【讨论】:

  • 非常感谢!确实有效。但是,您是否知道任何方法使用更简单的循环、枚举或字符串方法来找到相同的结果?我还没有从技术上学习你 re.sub 功能:(
  • 我添加了第二个解决方案,它只使用 replace() 函数和 in 运算符来检查是否可以在字符串中找到子字符串。如果您不允许使用它,那么您可以使用 find() 而不是 in 该行看起来像 if s.find('"') == -1: break
  • 非常感谢!太棒了。是否只要在字符串中留下“,它们就会被替换......但我想知道它是如何通过交替完成的。替换方法中的第三个字符我没有解释了吗?
  • 是的,这是逻辑:只要字符串中至少有一个双引号,我就会用“(”替换一个(找到的第一个双引号)(注意 ,1 中的参数替换函数,这意味着只替换遇到的第一个"。然后下一个双引号(如果找到)将被替换为“)”。
猜你喜欢
  • 1970-01-01
  • 2017-05-20
  • 1970-01-01
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-22
  • 2021-06-12
相关资源
最近更新 更多