Python重新提取数据之间的数据变化

时间:2018-04-12 02:12:52

标签: python regex

如果我有这个数据

NIST SP 800-53 :: CM-7
NIST SP 800-53A :: CM-7.1 (iii)
NIST SP 800-53 Revision 4 :: CM-7 b
NIST SP 800-53 :: IA-5 (1) (c)
NIST SP 800-53A :: IA-5 (1).1 (v)
NIST SP 800-53 Revision 4 :: IA-5 (1) (c)
NIST SP 800-53 :: IA-7
NIST SP 800-53A :: IA-7.1
NIST SP 800-53 Revision 4 :: IA-7
NIST SP 800-53 :: IA-7
NIST SP 800-53A :: IA-7.1
NIST SP 800-53 Revision 4 :: IA-7
NIST SP 800-53 :: SC-28
NIST SP 800-53A :: SC-28.1
NIST SP 800-53 Revision 4 :: SC-28
NIST SP 800-53 :: SC-23 (3)
NIST SP 800-53A :: SC-23 (3).1 (ii)
NIST SP 800-53 Revision 4 :: SC-23 (3)
NIST SP 800-53 :: SC-3
NIST SP 800-53A :: SC-3.1 (ii)

我只想检索“::”之后的值而没有别的,使用strip去除空格,如何使用re.sub将其转换为可以打印的变量。

对于

这样的行
NIST SP 800-53 Revision 4 :: IA-5 (1) (c)

我所追求的是字符串“IA-5”---在第一个打开的括号或空格开始后切断字符串的第一部分和任何东西?我必须说明没有括号的行,比如这行:

NIST SP 800-53 Revision 4 :: CM-7 b

我想要子串“CM-7”。

3 个答案:

答案 0 :(得分:1)

您不需要正则表达式。请勿完成xkcd 208

假设这些部分本身不包含空格或::,只需将::拆分,然后拆分空格

for line in open("data.txt"):
  parts = line.split("::")
  parts = list(map(str.strip, parts))
  print(parts[1].split()[0].strip())

输出

CM-7
CM-7.1
CM-7
IA-5
IA-5
IA-5
IA-7
IA-7.1
IA-7
IA-7
IA-7.1
IA-7
SC-28
SC-28.1
SC-28
SC-23
SC-23
SC-23
SC-3
SC-3.1

答案 1 :(得分:0)

而不是re.sub,请使用re.findall

import re
data = list(filter(None, input.split('\n')))
last_data = [re.findall('(?<=::\s)[a-zA-Z]+\-[\d\.]+', i)[0] for i in data]

输出:

['CM-7', 'CM-7.1', 'CM-7', 'IA-5', 'IA-5', 'IA-5', 'IA-7', 'IA-7.1', 'IA-7', 'IA-7', 'IA-7.1', 'IA-7', 'SC-28', 'SC-28.1', 'SC-28', 'SC-23', 'SC-23', 'SC-23', 'SC-3', 'SC-3.1']

答案 2 :(得分:0)

[re.sub('.*?::\s*(\S*)\s.*', '\g<1>', line, flags=re.DOTALL) for line in data]可以正常工作:)

我是捕获组子的忠实粉丝。

re.DOTALL将在行尾处理讨厌的空白)