如何用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实现,先分析原代码的问题:
- 变量名错误:
cols = l.split(" ")中的l应该是line - 分割方式错误:直接用空格分割会产生大量空字符串,因为表格是多空格分隔,应该用
split()(默认分割任意空白符) - 缺少位提取、转换逻辑,以及最终的写入步骤
以下是正确的实现代码:
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)
代码说明:
- extract_bit函数:用正则表达式提取
PS_XX[YY]格式字符串中的位数值YY - 标题行处理:直接读取并写入输出文件,保留表头格式
- 行处理逻辑:
- 分割每行数据为列列表
- 判断
new列是否为目标值,若是则提取位范围 - 通过位运算提取对应位段,转换为整数后格式化为32位十六进制字符串
- 按原表格的列宽格式化为对齐的行,写入输出文件
运行这段代码后,即可得到符合要求的输出文件。
内容的提问来源于stack exchange,提问作者V_S
相关产品推荐
相关产品推荐

