在字符串中反转标记的子字符串

时间:2016-03-18 20:03:00

标签: python string reversing

我有一个字符串,其中<>中的每个标记子字符串都在其中 必须颠倒(括号不嵌套)。例如,

"hello <wolfrevokcats>, how <t uoy era>oday?"

应该成为

 "hello stackoverflow, how are you today?"

我目前的想法是循环遍历字符串并找到索引对 <>的位置。然后简单地切割字符串并放入切片 再次与标记之间的所有内容相反。 这是正确的方法吗?是否有明显/更好的解决方案?

5 个答案:

答案 0 :(得分:8)

使用正则表达式非常简单。 re.sub将函数作为匹配对象传递的参数。

>>> import re
>>> s = 'hello <wolfrevokcats>, how <t uoy era>oday?'
>>> re.sub('<(.*?)>', lambda m: m.group(1)[::-1], s)
'hello stackoverflow, how are you today?'

正则表达式的解释:

<(.*?)>将匹配匹配组1中<>之间的所有内容。为了确保正则表达式引擎在第一个>符号出现处停止,延迟量词使用*?

传递给lambda m: m.group(1)[::-1]的函数re.sub获取匹配对象,提取组1,然后反转字符串。最后re.sub插入此返回值。

答案 1 :(得分:4)

或者,使用re.sub()替换功能

>>> import re 
s = 'hello <wolfrevokcats>, how <t uoy era>oday?'
>>> re.sub(r"<(.*?)>", lambda match: match.group(1)[::-1], s)
'hello stackoverflow, how are you today?'

其中.*?non-greedy方式任意次数匹配任何字符。围绕它的括号将帮助我们在group中捕获它,然后我们在替换函数中引用它match.group(1)[::-1]切片表示法reverses a string

答案 2 :(得分:3)

我将假设这是一项课程作业,不允许使用正则表达式。所以我将提供一个不使用它的解决方案。

content = "hello <wolfrevokcats>, how <t uoy era>oday?"

insert_pos = -1
result = []
placeholder_count = 0

for pos, ch in enumerate(content):
    if ch == '<':
        insert_pos = pos
    elif ch == '>':
        insert_pos = -1
        placeholder_count += 1
    elif insert_pos >= 0:
        result.insert(insert_pos - (placeholder_count * 2), ch)
    else:
        result.append(ch)

print("".join(result))

代码的要点是一次只能在字符串中传递一个字符。在括号外,只需将字符附加到结果字符串的末尾即可。在括号内,将字符插入左括号的位置(即预先悬挂字符)。

答案 3 :(得分:0)

我同意正则表达式是解决这个问题的正确工具,我喜欢Dmitry B.答案的要点。但是,我使用这个问题来练习生成器和函数式编程,我发布我的解决方案只是为了共享它。

msg = "<,woN> hello <wolfrevokcats>, how <t uoy era>oday?"

def traverse(s, d=">"):
    for c in s:
        if c in "<>": d = c
        else: yield c, d

def group(tt, dc=None):
    for c, d in tt:
        if d != dc:
            if dc is not None:
                yield dc, l
            l = [c]
            dc = d
        else:
            l.append(c)
    else: yield dc, l

def direct(groups):
    func = lambda d: list if d == ">" else reversed
    fst = lambda t: t[0]
    snd = lambda t: t[1]
    for gr in groups:
        yield func(fst(gr))(snd(gr))

def concat(groups):
    return "".join("".join(gr) for gr in groups)

print(concat(direct(group(traverse(msg)))))

#Now, hello stackoverflow, how are you today?

答案 4 :(得分:0)

这是另一个不使用正则表达式的情况:

def reverse_marked(str0):
    separators = ['<', '>']
    reverse = 0
    str1 = ['', str0]
    res = ''

    while len(str1) == 2:
        str1 = str1[1].split(separators[reverse], maxsplit=1)
        res = ''.join((res, str1[0][::-1] if reverse else str1[0]))
        reverse = 1 - reverse  # toggle 0 - 1 - 0 ...
    return res

print(reverse_marked('hello <wolfrevokcats>, how <t uoy era>oday?'))

输出:

hello stackoverflow, how are you today?
相关问题