返回不在括号内的字符串的索引

时间:2014-03-16 19:12:57

标签: python

假设我有一个字符串:

x = '[1.3].[1.2]'

如何找到不在方括号"."内的([])的第一个索引?

因此,对于上面的示例,第一个"."位于索引5处,它不在索引2处,因为在索引2处"."位于方括号内。

我尝试x.index("."),但只返回第一个"."的索引,而"."可以在括号内。

我也尝试过x.index('].[') + 1但是这个例子会失败:

x = '[[1.3].[9.10]].[1.2.[4.[5.6]]]'
x.index('].[') + 1
6

由于不在括号内的第一个"."位于索引13

如果有人能帮助我,我真的很感激。

这是什么,只是你有两个字符串以'['开头并以']'结尾,你用'。'连接它们,所以

s1 = "[1.2]"
s2 = "[2.3]"

s1 + "." + s2

基本上我正在尝试获取'。'的索引。字符串连接后。

2 个答案:

答案 0 :(得分:2)

一个简单的“解析器”:

def findRootIndexes (s):
    nested = 0
    for i, c in enumerate(s):
        if c == '[':
            nested += 1
        elif c == ']':
            nested -= 1
        elif c == '.' and nested == 0:
            yield i
>>> list(findRootIndexes('[1.3].[1.2]'))
[5]
>>> list(findRootIndexes('[[1.3].[9.10]].[1.2.[4.[5.6]]]'))
[14]
>>> list(findRootIndexes('[1.2].[3.4].[5.6]'))
[5, 11]

这基本上是pushdown automaton,除了我们不需要跟踪不同的标记而只需要开始和结束括号。所以我们只需要计算我们还有多少开放水平。


如果你想更进一步,你可以 - 正如roippi在评论中建议的那样 - 添加一些语法检查以防止像[[1.2]]]这样的事情。或者您还可以添加一些额外的检查,以确保开头[始终以点或其他开头[开头。要做到这一点,你可以使它成为一个单后看的解析器。像这样:

nested = 0
last = None
for i, c in enumerate(s):
    if c == '[':
        if last not in (None, '[', '.'):
            raise SyntaxError('Opening bracket must follow either `[` or `.`')
        nested += 1
    elif c == ']'
        if nested == 0:
            raise SyntaxError('Closing bracket for non-open group')
        nested -= 1
    elif c == '.' and nested == 0:
        yield i
    last = c

但是,当然,如果您自己从您知道有效的组件创建该字符串,则不一定需要这样的检查。

答案 1 :(得分:2)

在这个解决方案中,我们计算了左括号。这是我能想象到的最简单的方式:

x = '[[1.3].[9.10]].[1.2.[4.[5.6]]]'

brackets = 0
pos = 0

for y in x:
    if y == '[': 
        brackets += 1
    elif y == ']':
        brackets -=1

    if brackets == 0:
        print(pos) # Find first occurence and break from the loop
        break

    pos += 1

打印13