对字符进行标记,除了用方括号和保留方括号封装的字符



我正在解析我的击键数据。它看起来像这样:

> key_data = 'stuff[up][left][return]end'

我想对字符进行标记,但将[]包围的修饰符视为单个标记。

> print(key_tokens)
['s','t','u','f','f','[up]','[left]','[return]','e','n','d']

我知道我可以做这样的事情来找到封装的部分:

> key_tokens = re.split(r'([[]])', key_data)
> print(key_tokens)
['stuff','[','up',']','[','left',']','[','return',']','end']

当然我也可以这样做来分隔每个字符:

> key_tokens = [c for c in key_data]
> print(key_tokens)
['s','t','u','f','f','[','u','p',']','[','l','e','f','t',']','[','r','e','t','u','r','n',']','e','n','d']

我就是想不起来。

编辑:现在我看到一个角的情况下,开始方括号被用作文本。不幸的是,它没有被转义或其他。

> key_data = 'stuff[but[up][left][return]end'
> key_tokens = re.findall('[.*?]|.', key_data)
> print(key_tokens)
['s','t','u','f','f','[but[up]','[left]','[return]','e','n','d']

我想看到的是:

> print(key_tokens)
['s','t','u','f','f','[','b','u','t','[up]','[left]','[return]','e','n','d']

如果您不介意使用re.findall,而不是re.split,您可以首先尝试使用[.*?]来匹配方括号内的任何模式,如果不是,那么您可以只使用|.正在做的单个字符,它将匹配1长度的任何字符,如果您只有单词字符(即字母),因为您在样本数据中,您可以考虑使用|w:

>>> re.findall('[.*?]|.', key_data)
['s', 't', 'u', 'f', 'f', '[up]', '[left]', '[return]', 'e', 'n', 'd']

对于更新的问题:如果是这种情况,您可以考虑使用regex的替代品,因为它不太擅长处理这些类型的嵌套,因为值需要来回比较。下面是一个非正则表达式的解决方案:

result = []
idx = 0
while True:
    c = key_data[idx]
    if c != '[':
        idx += 1
        result.append(c)  #Append if not [
    else:
        closingIndex = key_data[idx+1:].find(']') # find if ] exist after current [
        if closingIndex == -1:
            #append the rest sub-srting and break since no ] after current [
            result.extend(key_data[idx:])
            break
        else:
            # Check if [ in the  middle, append only c if True
            if '[' in key_data[idx+1:idx+closingIndex+2]:
                result.append(c)
                idx += 1
            else:
                #Extend from [ to the nearest ]
                result.append(key_data[idx:idx+closingIndex+2])
                idx += closingIndex+2
    if idx>=len(key_data): break  #Break loop if idx exceeds maximum value

最新更新