Reverse marked substrings in a string

岁酱吖の 提交于 2020-12-12 06:21:08

问题


I have a string in which every marked substring within < and > has to be reversed (the brackets don't nest). For example,

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

should become

 "hello stackoverflow, how are you today?"

My current idea is to loop over the string and find pairs of indices where < and > are. Then simply slice the string and put the slices together again with everything that was in between the markers reversed. Is this a correct approach? Is there an obvious/better solution?


回答1:


It's pretty simple with regular expressions. re.sub takes a function as an argument to which the match object is passed.

>>> 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?'

Explanation of the regex:

<(.*?)> will match everything between < and > in matching group 1. To ensure that the regex engine will stop at the first > symbol occurrence, the lazy quantifier *? is used.

The function lambda m: m.group(1)[::-1] that is passed to re.sub takes the match object, extracts group 1, and reverses the string. Finally re.sub inserts this return value.




回答2:


Or, use re.sub() and a replacing function:

>>> 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?'

where .*? would match any characters any number of times in a non-greedy fashion. The parenthesis around it would help us to capture it in a group which we then refer to in the replacing function - match.group(1). [::-1] slice notation reverses a string.




回答3:


I'm going to assume this is a coursework assignment and the use of regular expressions isn't allowed. So I'm going to offer a solution that doesn't use it.

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))

The gist of the code is to have just a single pass at the string one character at a time. When outside the brackets, simply append the character at the end of the result string. When inside the brackets, insert the character at the position of the opening bracket (i.e. pre-pend the character).




回答4:


I agree that regular expressions is the proper tool to solve this problem, and I like the gist of Dmitry B.'s answer. However, I used this question to practice about generators and functional programming, and I post my solution just for sharing it.

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?



回答5:


Here's another one without using regular expressions:

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?'))

Output:

hello stackoverflow, how are you today?


来源:https://stackoverflow.com/questions/36093266/reverse-marked-substrings-in-a-string

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!