【问题标题】:extracting code from string using regex in python在python中使用正则表达式从字符串中提取代码
【发布时间】:2022-01-15 03:55:04
【问题描述】:

我正在尝试从字符串中提取汇编代码,但正则表达式不正确,因为我只能提取操作码而不是指令代码

import re
text = """
┌ 38: fcn.00014840 ();
│           ; var int64_t var_38h @ rsp+0xffffffd0
│           0x00014840      53             push rbx
│           0x00014841      31f6           xor esi, esi
│           0x00014843      31ff           xor edi, edi
│           0x00014845      e846f2feff     call sym.imp.getcwd
│           0x0001484a      4885c0         test rax, rax
│           0x0001484d      4889c3         mov rbx, rax
│       ┌─< 0x00014850      740e           je 0x14860
│       │   ; CODE XREF from fcn.00014840 @ 0x14868
│      ┌──> 0x00014852      4889d8         mov rax, rbx
│      ╎│   0x00014855      5b             pop rbx
│      ╎│   0x00014856      c3             ret
..
│      ╎│   ; CODE XREF from fcn.00014840 @ 0x14850
│      ╎└─> 0x00014860      e88beffeff     call sym.imp.__errno_location
│      ╎    0x00014865      83380c         cmp dword [rax], 0xc
│      └──< 0x00014868      75e8           jne 0x14852
└           0x0001486a      e861feffff     call fcn.000146d0
            ; CALL XREFS from fcn.00013d00 @ 0x13d9d, 0x13da8
"""

print("\n".join(re.findall('0x[0-9a-fA-F]{8}[0-9a-fA-F](.*?)',text)))

所以我想要这样的输出:

push rbx
xor esi, esi
xor edi, edi
call sym.imp.getcwd
test rax, rax
mov rbx, rax
je 0x14860
mov rax, rbx
pop rbx
ret
call sym.imp.__errno_location
cmp dword [rax], 0xc
jne 0x14852
call fcn.000146d0

【问题讨论】:

  • 对我来说,你可以在没有正则表达式的情况下做到这一点。代码总是从同一列开始,因此您可以使用索引 line[index:] 对每一行进行切片 - 最终它需要检查一些字符以跳过行 - 例如,当 line[12] 中有 ; 时,您可以跳过行

标签: python regex


【解决方案1】:

你可以试试这个:

out = "\n".join(re.findall(r"0x[0-9a-fA-F]{8} +[^ ]+ +([a-z].*)", text))
print(out)

它给出:

push rbx
xor esi, esi
xor edi, edi
call sym.imp.getcwd
test rax, rax
mov rbx, rax
je 0x14860
mov rax, rbx
pop rbx
ret
call sym.imp.__errno_location
cmp dword [rax], 0xc
jne 0x14852
call fcn.000146d0

【讨论】:

  • 不需要$和re.M
  • 没错,已编辑,谢谢。
【解决方案2】:

在您的模式 0x[0-9a-fA-F]{8}[0-9a-fA-F] 中,您在前 8 个字符之后匹配单个字符 [0-9a-fA-F],但示例数据中不存在该字符,因此不会匹配。

最后(.*?) 的捕获组也是非贪婪的,模式中没有任何内容。由于非贪婪匹配尽可能少,因此该组将始终为空。

对于模式,您可以使用:

\b0x[0-9a-f]{8}[^\S\n]+[0-9a-f]+[^\S\n]+(.+)

模式匹配:

  • \b0x[0-9a-f]{8}一个词边界,以防止部分词匹配
  • [^\S\n]+ 匹配 1+ 个没有换行符的空白字符
  • [0-9a-f]+ 匹配 1+ 次任何列出的范围 0-9 a-f
  • [^\S\n]+ 匹配 1+ 个不带换行符的空白字符
  • (.+)捕获group 1,匹配该行的其余部分(将由re.findall返回)

Regex demo

使用不区分大小写匹配的示例:

print("\n".join(re.findall(r"\b0x[0-9a-f]{8}[^\S\n]+[0-9a-f]+[^\S\n]+(.+)", text, re.I)))

输出

push rbx
xor esi, esi
xor edi, edi
call sym.imp.getcwd
test rax, rax
mov rbx, rax
je 0x14860
mov rax, rbx
pop rbx
ret
call sym.imp.__errno_location
cmp dword [rax], 0xc
jne 0x14852
call fcn.000146d0

【讨论】:

    【解决方案3】:

    您可以使用re.sub 将以下正则表达式的匹配项转换为空字符串:

    (?m)^(?:(?!.{12}0x[\da-fA-F]{8}).*\r?\n|.{43})
    

    Python regex ¯\(ツ)>Python code

    正则表达式可以分解如下(也可以将光标悬停在“Python regex”链接处表达式的每个部分上,以获得对其功能的解释)。

    (?m)              # set multiline flag causing '^' and '$' to match
                      # the beginning and end of each line respectively
    ^                 # match beginning of line
    (?:               # begin non-capture group
      (?!             # begin negative lookahead
        .{12}0x       # match 12 characters followed by '0x'
        [\da-fA-F]{8} # match 8 characters contained in the character class
      )               # end negative lookahead
      .*\r?\n         # match the entire line including the terminator
    |                 # or
      .{43}           # match 43 characters
    )                 # end non-capture group
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-10-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-12-19
      • 2014-08-25
      • 1970-01-01
      相关资源
      最近更新 更多