You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Python从十六进制数提取指定位并处理文本文件?

用Python实现特定位提取并更新表格数据

需求说明

输入文件input.txt内容如下:

PS name         above bit      below bit      original            1_info           2_info            new      
PS_AS_0         PS_00[31]      PS_00[00]      0x00000000          0x156A17[00]     0x156A17[31]      0x0003F4a1 
PS_RST_D2       PS_03[05]      PS_03[00]      0x00000003          0x1678A1[00]     0x1678A1[05]      0x0a56F001
PS_N_YD_C       PS_03[06]      PS_03[06]      0x00000000          0x1678A1[06]     0x1678A1[06]      0x0a56F001
PS_1_FG         PS_03[31]      PS_03[07]      0x000000FF          0x1678A1[07]     0x1678A1[31]      0x0a56F001
PS_F_23_ASD     PS_04[07]      PS_03[00]      0x00000000          0x18C550[00]     0x18C550[07]      0x00000000
PS_A_0_STR      PS_04[15]      PS_04[08]      0x00000FFF          0x18C550[08]     0x18C550[15]      0x00000000
PS_AD_0         PS_04[31]      PS_04[16]      0x00000000          0x18C550[16]     0x18C550[31]      0x00000000

需要按以下规则处理每行数据:

  • 当new列的值为0x0a56F001时,先将其转换为32位二进制(如0000 1010 0101 0110 1111 0000 0000 0001)
  • 从above bit和below bit列中提取位范围(比如PS_03[05]和PS_03[00]对应第0到5位)
  • 截取该二进制值对应位段,转换为十六进制并格式化为32位带0x的形式,替换原new列的值

处理后的期望输出文件内容如下:

PS name         above bit      below bit      original            1_info           2_info            new      
PS_AS_0         PS_00[31]      PS_00[00]      0x00000000          0x156A17[00]     0x156A17[31]      0x0003F4a1 
PS_RST_D2       PS_03[05]      PS_03[00]      0x00000003          0x1678A1[00]     0x1678A1[05]      0x00000001
PS_N_YD_C       PS_03[06]      PS_03[06]      0x00000000          0x1678A1[06]     0x1678A1[06]      0x00000000
PS_1_FG         PS_03[31]      PS_03[07]      0x000000FF          0x1678A1[07]     0x1678A1[31]      0x0014ADE0
PS_F_23_ASD     PS_04[07]      PS_03[00]      0x00000000          0x18C550[00]     0x18C550[07]      0x00000000
PS_A_0_STR      PS_04[15]      PS_04[08]      0x00000FFF          0x18C550[08]     0x18C550[15]      0x00000000
PS_AD_0         PS_04[31]      PS_04[16]      0x00000000          0x18C550[16]     0x18C550[31]      0x00000000

用户尝试的代码无法正常工作:

with open("input.txt") as fin:
    with open("output.txt", "w") as fout:
         for line in fin:
             if line.strip():
                 line = line.strip("\n' '")
                 cols = l.split(" ")
                 cols[6] = int(cols[6],16)

解决方案

这个需求完全可以用Python实现,先分析原代码的问题:

  1. 变量名错误:cols = l.split(" ")中的l应该是line
  2. 分割方式错误:直接用空格分割会产生大量空字符串,因为表格是多空格分隔,应该用split()(默认分割任意空白符)
  3. 缺少位提取、转换逻辑,以及最终的写入步骤

以下是正确的实现代码:

import re

# 提取括号内的数字
def extract_bit(bit_str):
    match = re.search(r'\[(\d+)\]', bit_str)
    if match:
        return int(match.group(1))
    return 0

with open("input.txt", "r") as fin:
    with open("output.txt", "w") as fout:
        # 读取标题行并直接写入
        header = fin.readline()
        fout.write(header)
        
        for line in fin:
            line = line.strip()
            if not line:
                continue
            # 按任意空白符分割列
            cols = line.split()
            new_val = cols[6]
            # 只处理new列是0x0a56F001的行
            if new_val.lower() == '0x0a56f001':
                # 转换为整数
                new_int = int(new_val, 16)
                # 提取上下位
                above_bit = extract_bit(cols[1])
                below_bit = extract_bit(cols[2])
                # 确定位范围:低位到高位
                low_bit = min(above_bit, below_bit)
                high_bit = max(above_bit, below_bit)
                # 计算掩码,提取对应位段
                bit_length = high_bit - low_bit + 1
                mask = ( (1 << bit_length) - 1 ) << low_bit
                # 提取位段并右移到最低位
                extracted = (new_int & mask) >> low_bit
                # 格式化为32位十六进制字符串
                cols[6] = f"0x{extracted:08X}"
            # 重新拼接成对齐的行(保持原格式的列宽)
            formatted_line = f"{cols[0]:<14}{cols[1]:<14}{cols[2]:<14}{cols[3]:<20}{cols[4]:<16}{cols[5]:<16}{cols[6]:<12}\n"
            fout.write(formatted_line)

代码说明:

  1. extract_bit函数:用正则表达式提取PS_XX[YY]格式字符串中的位数值YY
  2. 标题行处理:直接读取并写入输出文件,保留表头格式
  3. 行处理逻辑:
    • 分割每行数据为列列表
    • 判断new列是否为目标值,若是则提取位范围
    • 通过位运算提取对应位段,转换为整数后格式化为32位十六进制字符串
    • 按原表格的列宽格式化为对齐的行,写入输出文件

运行这段代码后,即可得到符合要求的输出文件。

内容的提问来源于stack exchange,提问作者V_S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.12 15:30:53