如何解析某些文本数据?

时间:2016-08-18 13:06:22

标签: python text-processing

我有一个格式如下的文本文件:

B2100 Door Driver Key Cylinder Switch Failure B2101 Head Rest Switch Circuit Failure B2102 Antenna Circuit Short to Ground`, plus 1000 lines more.

这就是我想要的:

B2100*Door Driver Key Cylinder Switch Failure B2101*Head Rest Switch Circuit Failure B2102*Antenna Circuit Short to Ground B2103*Antenna Not Connected B2104*Door Passenger Key Cylinder Switch Failure

这样我就可以在LibreOffice Calc中复制这些数据,它会将其格式化为两列代码,并将其分别表示。

我的思考过程:
在Bxxxx上应用常规快递并在其前面放一个星号(它作为分隔符)和\n之前的含义(我不知道这是否有用?),并删除空格直到遇到下一个字符。

我试图隔离B2100并且直到现在都失败了。我天真的尝试:

import re

text = """B2100 Door Driver Key Cylinder Switch Failure B2101   Head Rest Switch Circuit Failure B2102  Antenna Circuit Short to Ground B2103   Antenna Not Connected B2104 Door Passenger Key Cylinder Switch Failure B2105    Throttle Position Input Out of Range Low B2106  Throttle Position Input Out of Range High B2107 Front Wiper Motor Relay Circuit Short to Vbatt B2108    Trunk Key Cylinder Switch Failure"""
# text_arr = text.split("\^B[0-9][0-9][0-9][0-9]$\gi");
l = re.compile('\^B[0-9][0-9][0-9][0-9]$\gi').split(text)
print(l)

输出:

['B2100\tDoor Driver Key Cylinder Switch Failure B2101\tHead Rest Switch Circuit Failure B2102\tAntenna Circuit Short to Ground B2103\tAntenna Not Connected B2104\tDoor Passenger Key Cylinder Switch Failure B2105\tThrottle Position Input Out of Range Low B2106\tThrottle Position Input Out of Range High B2107\tFront Wiper Motor Relay Circuit Short to Vbatt B2108\tTrunk Key Cylinder Switch Failure']

如何达到预期效果?

为了进一步细分,我想做的是:
将所有内容分解为代码(B1001)和含义(后面的文本)数组,然后单独应用每个操作(\n事物)。如果你对如何做好整件事有更好的想法,那就更好了。我很乐意听到它。

4 个答案:

答案 0 :(得分:5)

基本上,你想要:

  • 在输入中查找任何Bxxxx字符串。
  • 使用换行符替换前面的任何空格。
  • 使用*替换后面的任何空格。

这一切都可以通过一个re.sub()完成:

re.sub(r'\s*(B\d{4})\s*', r'\n\1*', text).strip()

匹配模式:

\s*              # Any amount of whitespace
   (B\d{4})      # "B" followed by exactly 4 digits
           \s*   # Any amount of whitespace

替换模式:

\n               # Newline
  \1             # The first parenthesized sequence from the matching pattern (B####)
    *            # Literal "*"

strip()的目的是修剪任何前导或尾随空格,包括第一个B ####序列的子行所产生的换行符。

答案 1 :(得分:0)

首先,你的正则表达式是错误的 “\ ^ B [0-9] [0-9] [0-9] [0-9] $ \ GI

  1. 修饰符在Python上不起作用
  2. ^和$表示该行的开头和结尾,与文字中的任何内容都不匹配
  3. 倍数[0-9]可以替换为'[0-9] {4}'
  4. 如果你想忽略大小写,请在Python regex
  5. 上使用相应的东西

    考虑到这一点,一个简单的代码来实现你想要的东西是这样的:

    l = [x.strip() for x in re.compile('\s*(B\d{4})\s*', re.IGNORECASE).split(text)]
    lines = ['*'.join(l[i:i+2]) for i in range(0,len(l),2)]
    

答案 2 :(得分:0)

import re
text = """B2100 Door Driver Key Cylinder Switch Failure B2101   Head Rest Switch Circuit Failure B2102  Antenna Circuit Short to Ground B2103   Antenna Not Connected B2104 Door Passenger Key Cylinder Switch Failure B2105    Throttle Position Input Out of Range Low B2106  Throttle Position Input Out of Range High B2107 Front Wiper Motor Relay Circuit Short to Vbatt B2108    Trunk Key Cylinder Switch Failure"""

l = [i for i in re.split('(B[0-9]{4}\s+)', text) if i]
print '\n'.join(['{}*{}'.format(id_.strip(), label.strip()) for id_,label in zip(l[0::2], l[1::2])])
如果在正则表达式周围包含(),

.split可以在拆分后保留分隔符。以上产生输出:

B2100*Door Driver Key Cylinder Switch Failure
B2101*Head Rest Switch Circuit Failure
B2102*Antenna Circuit Short to Ground
B2103*Antenna Not Connected
B2104*Door Passenger Key Cylinder Switch Failure
B2105*Throttle Position Input Out of Range Low
B2106*Throttle Position Input Out of Range High
B2107*Front Wiper Motor Relay Circuit Short to Vbatt
B2108*Trunk Key Cylinder Switch Failure

答案 3 :(得分:0)

导入重新

将pandas导入为pd

pat = r"(B \ d +)"

zzz = [i for i in re.split(pat,kkk)if if!='']

pd.DataFrame({' Col1':zzz [:: 2],' Col2':[i.strip()for i in zzz if re.match(pat, i)是None]})

Col1 Col2

0 B2100门驱动器钥匙开关故障

1 B2101头枕开关电路故障

2 B2102天线电路对地短路 3 B2100门驱动器钥匙开关故障