4

我正在使用 python 使用正则表达式解析出 SDDL。SDDL 始终采用“类型:某些文本”的形式,最多重复 4 次。类型可以是“O”、“G”、“D”或“S”,后跟冒号。“一些文本”的长度是可变的。

这是一个示例 SDDL:

O:DAG:S-1-5-21-2021943911-1813009066-4215039422-1735D:(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)S:NO_ACCESS_CONTROL

这是我到目前为止所拥有的。其中两个元组返回得很好,但另外两个 - ('G','S-1-5-21-2021943911-1813009066-4215039422-1735') 和 ('S','NO_ACCESS_CONTROL') 不是。

import re

sddl="O:DAG:S-1-5-21-2021943911-1813009066-4215039422-1735D:(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)S:NO_ACCESS_CONTROL"

matches = re.findall('(.):(.*?).:',sddl)

print matches

[('O', 'DA'), ('D', '(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)')]

我想要返回的是

[('O', 'DA'), ('G','S-1-5-21-2021943911-1813009066-4215039422-1735'), ('D', '(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)'),('S','NO_ACCESS_CONTROL')]
4

2 回答 2

2

尝试以下操作:

(.):(.*?)(?=.:|$)

例子:

>>> re.findall(r'(.):(.*?)(?=.:|$)', sddl)
[('O', 'DA'), ('G', 'S-1-5-21-2021943911-1813009066-4215039422-1735'), ('D', '(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)'), ('S', 'NO_ACCESS_CONTROL')]

此正则表达式的开始方式与您的相同,但不是.:在末尾包含作为匹配的一部分,而是使用前瞻。这是必要的,因为re.findall()不会返回重叠匹配,因此您需要在下一个匹配开始之前停止每个匹配。

前瞻(?=.:|$)本质上意味着“仅当下一个字符是后跟冒号的任何字符,或者我们位于字符串的末尾时才匹配”。

于 2012-08-27T18:07:48.330 回答
0

似乎使用正则表达式并不是解决此问题的最佳方法。实际上,您要做的就是拆分冒号,然后对结果列表进行一些转换。

chunks = sddl.split(':')
pairs = [(chunks[i][-1], chunks[i+1][:-1] \
                             if i < (len(chunks) - 2) \
                             else chunks[i+1]) 
               for i in range(0, len(chunks) - 1)]
于 2012-08-27T18:25:37.743 回答