【问题标题】:Extracting repetitions through regex in Python在 Python 中通过正则表达式提取重复项
【发布时间】:2016-01-11 12:27:24
【问题描述】:

我正在尝试从通过正则表达式提供的大量数据中提取一些有用的数据。
示例字符串:

test 1:
hello op1 yviphf
hello op2 vipqwe
test 2:
hello op3
hello op4 vipgt
hello op5 zcv

以上包含 2 个测试编号,但也有多个。我想提取 op1、op2、op3、op4、op5 以及相应的测试编号。每个测试中的操作数可能会有所不同。
以下是我尝试编写但无济于事的模式:

test\s(\d+).*?(?:hello\s+(\S+).*?\n)+

输出可以是列表列表。主列表将第一个元素作为测试编号,第二个元素可能是包含所有操作的列表。

【问题讨论】:

  • 分两步完成:首先匹配完整的部分,然后为每个部分匹配 op 值。
  • 你需要使用正则表达式吗?
  • 您在寻找/s 标志吗?见regex101.com/r/nU8aA5/1
  • this 会做吗?
  • 你应该给出一个更好的示例字符串(更现实),因为它很难回答。 (实际上看起来如何,“hello”这个词是否开始每一行?)。如果你有很多数据,逐行工作更好,也许你可以避免正则表达式并获得更快的结果。

标签: python regex pattern-matching


【解决方案1】:

我建议基于正则表达式的 3 步方法。

  • 首先,使用r'test\s*(\d+)'re.findall 获取所有测试编号(这将仅获取编号列表,因为\d+ 子模式位于捕获组内)
  • 其次,使用test\s*\d+ 正则表达式拆分输入字符串以获得带有hello 代码的小节,并在每个非-空块(同样,re.findall 只会获取 \S+ 子匹配,因为它包含在捕获组中)
  • 将列表合并成一个元组列表。

Python demo:

import re
test_str = "test 1:\nhello op1 yviphf\nhello op2 vipqwe\ntest 2:\nhello op3\nhello op4 vipgt\nhello op5 zcv"
res1 = [y for y in re.findall(r'test\s*(\d+)', test_str) if y]
res2 = [re.findall(r'(?m)^hello\s*(\S+)', b) for b in re.split(r'test\s*\d+', test_str) if b]
print(zip(res1, res2))

结果:[('1', ['op1', 'op2']), ('2', ['op3', 'op4', 'op5'])]

【讨论】:

    【解决方案2】:

    您需要使用正则表达式吗?

    如果没有,您可以使用循环、字符串比较和拆分:

    data = {}
    key = '_'
    for linea in text.split('\n'):
        if "test" in linea:
            key = linea.split()[1][:-1]
            data[key]=[]
        else:
            _data_ = linea.split()[1]
            data[key].append(_data_)
    
    print data
    > {'1': ['op1', 'op2'], '2': ['op3', 'op4', 'op5']}
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-16
      • 2022-11-15
      • 2016-10-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多