查找python代码段中出现的所有字节字符串



我试图解析python片段,其中一些包含字节串。例如:

"""
from gzip import decompress as __;_=exec;_(__(b'x1fx8bx08x00xcbYmcx02xffxbd7ixb3xdaJvxdfxdfxaf /Ixf9xbarxc6%x81@x92kx9c)x16I,bx95Xmx87x92Z-$xd0x86x16x10LM~{Nx03xd7xc6xd7x9e%xa9xa9PE/xa7xcfxbeukxd3xacmxdd"x94x1b'xa5xdax04"Hx17xaexe3txf4xcdnx03xa9/&T>x13xdbug=x9fx13~x11xf6x9bxd7x15~xb2xe7xbcxe6xc2Kxb8x18x03xfd|[x7fxe8xb8I;xf0xf1x93xecx83x8eo15x8dCxfcxc6Ixf1xfdxf5rx8fxebx0fxd7xc53#xa8<_xb2Pyxbexe1xdexffx0fk&x93xa8Vx18x00x00'))
x = b"x1fx8bx08"
y = "hello world"
"""

是否有一个正则表达式模式,我可以使用正确地找到这些字符串?

我已经尝试实现一个正则表达式查询自己,像这样:

bytestrings= re.findall(r'b"(.+?)"', text) + re.findall(r"b'(.+?)'", text)

我期望收到一个数组

[b'x1fx8bx08x00xcbYmcx02xffxbd7ixb3xdaJvxdfxdfxaf /Ixf9xbarxc6%x81@x92kx9c)x16I,bx95Xmx87x92Z-$xd0x86x16x10LM~{Nx03xd7xc6xd7x9e%xa9xa9PE/xa7xcfxbeukxd3xacmxdd"x94x1b'xa5xdax04"Hx17xaexe3txf4xcdnx03xa9/&T>x13xdbug=x9fx13~x11xf6x9bxd7x15~xb2xe7xbcxe6xc2Kxb8x18x03xfd|[x7fxe8xb8I;xf0xf1x93xecx83x8eo15x8dCxfcxc6Ixf1xfdxf5rx8fxebx0fxd7xc53#xa8<_xb2Pyxbexe1xdexffx0fk&x93xa8Vx18x00x00', b"x1fx8bx08"]

返回一个空数组。

这不是正则表达式的工作,而是Python解析器的工作。

import ast
code = """
...
"""
tree = ast.parse(code)

现在您可以遍历树,寻找value属性为bytes类型的ast.Constant类型的值。通过定义ast.NodeVisitor的子类并重写其visit_Constant方法来实现。该方法将在树中类型为ast.Constant的每个节点上调用,让您检查该值。在这里,我们只是向全局列表中添加适当的值。

bytes_literals = []
class BytesLiteralCollector(ast.NodeVisitor):
def visit_Constant(self, node):
if isinstance(node.value, bytes):
bytes_literals.append(node.value)
BytesLiteralCollector().visit(tree)

NodeVisitor的文档不是很好。除了两个文档方法visitgeneric_visit之外,我相信您可以定义visit_*,其中*可以是文档开头提供的抽象语法中定义的任何节点类型。

您可以使用print(ast.dump(ast.parse(code), indent=4))来获得访问者将走过的树的或多或少可读的表示。

最新更新