我正在解析我的击键数据。它看起来像这样:
> 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