【问题标题】:Need help to extract data pattern from a list as shown below需要帮助从列表中提取数据模式,如下所示
【发布时间】:2018-07-23 12:24:28
【问题描述】:

我有如下所示的数据示例,我想提取具有如下键/值模式的数据:

'Signature Algorithm: ecdsa-with-SHA256', 'Not Before: Jul 23 00:00:00 2018 GMT', 'Not After : Jul 19 00:00:00 2033 GMT, 'Public Key Algorithm: id-ecPublicKeyid', Public-Key: (256 bit)' 

例子:

['Certificate:', 'Data:', 'Version: 3 (0x2)', 'Serial Number:', 'b9:d9:f5:38:f8:42:6a:f9', 'Signature Algorithm: ecdsa-with-SHA256', 'Issuer: C=US, ST=NC, L=Raleigh, O=Eaton Corporation, OU=Electrical Division, CN=PowerXpert-02-00-34-56-63-01', 'Validity', 'Not Before: Jul 23 00:00:00 2018 GMT', 'Not After : Jul 19 00:00:00 2033 GMT', 'Subject: C=US, ST=NC, L=Raleigh, O=Eaton Corporation, OU=Electrical Division, CN=PowerXpert-02-00-34-56-63-01', 'Subject Public Key Info:', 'Public Key Algorithm: id-ecPublicKey', 'Public-Key: (256 bit)', 'pub:', '04:bf:72:4b:01:8b:5c:46:98:96:a6:d6:06:7b:d8:', '73:50:2f:47:85:60:f0:38:25:79:3d:96:be:20:3b:', '3f:39:c8:58:62:e9:d7:b6:f8:3a:6b:24:50:e1:5c:', '78:ce:5e:28:f2:60:3a:b6:cc:43:0e:0b:2b:d6:03:', '51:76:21:a4:78', 'ASN1 OID: prime256v1', 'NIST CURVE: P-256', 'X509v3 extensions:', 'X509v3 Subject Key Identifier:', '6A:E0:28:A7:17:2B:65:01:FD:31:48:5C:68:24:94:4B:42:49:76:58', 'X509v3 Basic Constraints: critical', 'CA:TRUE', 'X509v3 Key Usage: critical', 'Digital Signature, Certificate Sign, CRL Sign', 'X509v3 Subject Alternative Name:', 'DNS:PXG900-56-63-01', 'Signature Algorithm: ecdsa-with-SHA256', '30:45:02:20:43:33:58:ce:ef:f7:fd:a8:60:21:15:a3:2b:35:', '8c:1f:13:a0:1e:77:05:6f:1a:bb:a0:b6:fe:f3:ea:7b:6d:31:', '02:21:00:cf:db:9a:d1:6b:88:ae:fb:d5:5c:5a:db:0a:a0:eb:', 'a9:c9:4a:52:d0:57:18:9c:58:1b:67:42:47:c5:ec:bf:b0', '', '']

使用下面的正则表达式但没有得到想要的结果

regex = re.compile(r'''
[\S]+:                # a key (any word followed by a colon)
(?:
\s                    # then a space in between
(?!\S+:)\S+           # then a value (any word not followed by a colon)
)+                    # match multiple values if present
''', re.VERBOSE)

matches = regex.findall(str(lines))
print(matches)

【问题讨论】:

  • lines 这是一个列表吗?
  • 是的行是数据列表
  • 想要的结果是什么?请格式化问题。
  • 从显示的列表中,我想要数据的键/值模式,例如('签名算法:ecdsa-with-SHA256','Not Before: Jul 23 00:00:00 2018 GMT', '不是之后:格林威治标准时间 2033 年 7 月 19 日 00:00:00')
  • 你可以把它变成一个字典并按照你想要的方式使用它:dictionary = eval(re.sub(r"\s*'?([^,']+?)\s*:\s*([^,']+)[',]*",r"'\1':'\2',",a).join('{}')) 其中a 是你给的字符串。或者更确切地说,您可以将其拆分 a.split(",") 以生成下面给出的答案

标签: regex python-3.x python-2.7


【解决方案1】:

您可以使用以下正则表达式:

(?='[A-Za-z]+[\s-][A-Z][a-z]+\s?:?)'[^']+:[^']+'

  • (?= 积极前瞻。断言以下内容是:
    • '[A-Za-z]+,撇号 ' 字符,后跟字母字符。
    • [\s-] 空格或破折号 -
    • [A-Za-z]+ 字母字符。
    • \s? 可选空格。
    • :?\s 可选冒号 : 后跟空格。
  • ) 关闭前瞻。

  • '[^']+ 匹配撇号 ' 字符,任何不是撇号 ' 字符的字符。

  • : 匹配冒号。

  • [^']+' 匹配任何不是撇号' 字符,后跟撇号'

您可以实时测试正则表达式here


Python sn-p:

import re
lines = ['Certificate:', 'Data:', 'Version: 3 (0x2)', 'Serial Number:', 'b9:d9:f5:38:f8:42:6a:f9', 'Signature Algorithm: ecdsa-with-SHA256', 'Issuer: C=US, ST=NC, L=Raleigh, O=Eaton Corporation, OU=Electrical Division, CN=PowerXpert-02-00-34-56-63-01', 'Validity', 'Not Before: Jul 23 00:00:00 2018 GMT', 'Not After : Jul 19 00:00:00 2033 GMT','Public Key Algorithm: id-ecPublicKey',
'Public-Key: (256 bit)']
matches = re.findall(r"(?='[A-Za-z]+[\s-][A-Z][a-z]+\s?:?)'[^']+:[^']+'",str(lines))
for match in matches:
    print (match)

输出:

'Signature Algorithm: ecdsa-with-SHA256'
'Not Before: Jul 23 00:00:00 2018 GMT'
'Not After : Jul 19 00:00:00 2033 GMT'
'Public Key Algorithm: id-ecPublicKey'
'Public-Key: (256 bit)'
'Signature Algorithm: ecdsa-with-SHA256'

【讨论】:

  • 谢谢,这行得通,但是如果我们还有一些像下面这样的数据也将与前一个数据一起提取呢? '公钥算法:id-ecPublicKey','公钥:(256位)'
  • @coding_learner 请将所有附加信息添加到原始问题中。
  • @coding_learner 我已经用其他案例更新了我的答案,因为问题已解决,请考虑接受答案。请在此处查看操作方法。
  • 这不只是lines.split(",")吗?
  • @Onyambu 不。如果你查看打开的帖子,他不想要每一对 key : value 而是只想要特定的条目。
【解决方案2】:

我不确定我是否完全理解。但是你就不能走吗:

extracted = []
for item in lines:
    if len(item.split(": ")) == 2: # It has 2 items
        extracted.append(item)

这将提取在“:”两侧具有“东西”的每个项目。 我希望这会有所帮助。

【讨论】:

  • 它非常适合各种数据!
【解决方案3】:

您可以使用这个正则表达式来提取键值对。

([a-zA-Z0-9 ]*:[a-zA-Z0-9\- :]*)

Demo Link

【讨论】:

  • 使用您的建议,它正在提取所有键值,但包括具有空间值的键。示例:pub:任何东西:
  • 我不想要那个没有价值的键,我的意思是说忽略价值作为一个 spce
  • 我没明白。您有 3 个键值对。此正则表达式查找所有键值对,在您的情况下为 3,您可以将其作为列表并使用简单的正则表达式在循环中分隔键值对。
  • @coding_learner 您的指示不清楚。如果您想要每个键值对,为什么 Version: 3 (0x2) 不在所需的输出中?我的理解是只匹配某些模式,这就是我的正则表达式所做的。
  • @nikesh:我使用你的正则表达式得到的输出基本上也可以从一个简单的 for 循环中得到...... for match in lines:print(match) 完全相同的输出然后是什么正则表达式在这里?
【解决方案4】:
 re.findall("'[A-Z][^':]+:[^',:]+(?:\d{2}:){0,3}[^',:]+'(?=,)",str(lines))
Out[139]: 
["'Version: 3 (0x2)'",
 "'Signature Algorithm: ecdsa-with-SHA256'",
 "'Not Before: Jul 23 00:00:00 2018 GMT'",
 "'Not After : Jul 19 00:00:00 2033 GMT'",
 "'Public Key Algorithm: id-ecPublicKey'",
 "'Public-Key: (256 bit)'",
 "'ASN1 OID: prime256v1'",
 "'NIST CURVE: P-256'",
 "'X509v3 Basic Constraints: critical'",
 "'CA:TRUE'",
 "'X509v3 Key Usage: critical'",
 "'DNS:PXG900-56-63-01'",
 "'Signature Algorithm: ecdsa-with-SHA256'"]

【讨论】:

  • 'Version: 3 (0x2),b9:d9, 'Issuer: C=US 不在所需的输出中。
  • 这也缺少Public-Key: (256 bit),它包含在期望的结果中
  • @UnbearableLightness 我已经编辑了答案。您现在可以删除您的反对票。 Version: 3 (0x2) 也应该在那里,因为它具有键值模式。打印的结果是 OP 正在寻找的示例。
  • 我的理解是他只想要特定的条目。否则他应该只是说我想要每个键值对 ...
  • @UnbearableLightness OP 明确表示他们想要键值。尝试运行接受的解决方案,你会明白我在说什么
猜你喜欢
  • 1970-01-01
  • 2023-04-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多