只有当字符不在括号内时才替换字符

3

我有一个如下的字符串:

test_string = "test:(apple:orange,(orange:apple)):test2"

我希望将“:”替换为“/”,但仅当它不包含在任何一组括号中时。
期望的输出是“test/(apple:orange,(orange:apple))/test2”。
如何在Python中实现这个目标?

期望的输出? - DirtyBit
@user5173426 请查看编辑后的帖子。谢谢! - Jack Arnestad
3
逐个遍历字符,在遇到 ( 时计数器加一,在遇到 ) 时减一,如果字符匹配且计数器为零,则替换。祝实现愉快! - Klaus D.
3个回答

4
你可以使用以下代码来实现预期的输出。
def solve(args):
    ans=''
    seen = 0
    for i in args:
        if i == '(':
            seen += 1
        elif i== ')':
            seen -= 1
        if i == ':' and seen <= 0:
            ans += '/'
        else:
            ans += i
    return ans

test_string = "test:(apple:orange,(orange:apple)):test2"
print(solve(test_string))

2
使用正则表达式模块(regex)可以实现以下功能:
>>> import regex
>>> test_string = "test:(apple:orange,(orange:apple)):test2"
>>> regex.sub(r'\((?:[^()]++|(?0))++\)(*SKIP)(*F)|:', '/', test_string)
'test/(apple:orange,(orange:apple))/test2'
  • \((?:[^()]++|(?0))++\) 递归匹配括号对
  • (*SKIP)(*F) 避免替换前面的模式
  • |: 指定:作为备选匹配项

很酷啊!!! 如果您不介意,能否分享一下您学习这种正则表达式的资源? - Mayur
1
@Mayur,我从很多地方收集了信息,其中一些来自于SO上的regex标签,还有一些来自于答案中提到的链接。我在github上整理了一个资源列表,可能会有所帮助。 - Sundeep
谢谢!如果我想检查它是否在括号 {...} 中,而不是圆括号,该怎么办? - Jack Arnestad
@JackArnestad 将所有的括号改为花括号,除了以 (? 开头的对。 - Sundeep

0
  1. 找到第一个左括号
  2. 找到最后一个右括号
  3. 将第一个左括号之前的每个“:”替换为“/”
  4. 不要对中间部分做任何事情
  5. 将最后一个右括号之后的每个“:”替换为“/”
  6. 将这3个子字符串放在一起

代码:

test_string = "test:(apple:orange,(orange:apple)):test2"
first_opening = test_string.find('(')
last_closing = test_string.rfind(')')
result_string = test_string[:first_opening].replace(':', '/') + test_string[first_opening : last_closing] +  test_string[last_closing:].replace(':', '/')
print(result_string)

输出:

test/(apple:orange,(orange:apple))/test2

警告:正如注释所指出的那样,如果有多个不同的括号,这种方法将无法工作 :(


2
这种方法无法处理任意深度的嵌套括号。 - Tim Biegeleisen
适用于这个特定的例子;不适用于符合 OP 描述的一般情况(例如:(apple:orange):test:(orange:apple))。 - Amadan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接