【问题标题】:fetch specific protobuf members获取特定的 protobuf 成员
【发布时间】:2021-09-07 20:30:49
【问题描述】:

我想获取以text: 开头的所有行的数组(直到第一个asset_performance_label

我看到了这个post,但不知道如何应用它。

我应该像我尝试过的那样将 proto 转换为字符串吗?

    text = extract_text_from_proto(r"(\w+)text:(\w+)asset_performance_label:", '''[pinned_field: HEADLINE_1
    text: "5 Best Products"
    asset_performance_label: PENDING
    policy_summary_info
    {
        review_status: REVIEWED
        approval_status: APPROVED
    }
    , pinned_field: HEADLINE_1
    text: "10 Best Products 2021"
    asset_performance_label: PENDING
    policy_summary_info
    {
        review_status: REVIEWED
        approval_status: APPROVED
    }''')


def extract_text_from_proto(regex, proto_string):
    regex = re.escape(regex)
    result_array = [m.group() for m in re.finditer(regex, proto_string)]
    return result_array
    # return [extract_text(each_item, regex) for each_item in proto],


def extract_text(regex, item):
    m = re.match(regex, str(item))
    if m is None:
        # text = "MISSING TEXT"
        raise Exception("Ad is missing text")
    else:
        text = m.group(2)
    return text

预期结果:["5 Best Products","10 Best Products 2021"]

如果我想匹配(可选)pinned_field: (word) 怎么办?所以结果可能是:[HEADLINE_1: 5 Best Products', 'HEADLINE_1:10 Best Products 2021', 'some_text_without_pinned_field']` ?

【问题讨论】:

  • 所以你想匹配5 Best Products10 Best Products 2021
  • 是的,请Expected result: ["5 Best Products","10 Best Products 2021"]`

标签: python-3.x regex protocol-buffers proto


【解决方案1】:

您可以使用单个捕获组,并在下一行匹配 assert_performance_label。使用 re.findall 返回组值。

\btext:\s*"([^"]+)"\n\s*asset_performance_label\b

模式匹配

  • \btext:\s*" 匹配 text: 前面的单词边界 \b 以防止部分匹配
  • ([^"]+) 捕获第 1 组,匹配除双引号以外的 1+ 个字符
  • "\n\s* 匹配换行符和可选的空白字符
  • asset_performance_label\b 匹配 `asset_performance_label 后跟单词边界

例如

import re

def extract_text_from_proto(regex, proto_string):
    return re.findall(regex, proto_string)

text = extract_text_from_proto(r'\btext:\s*"([^"]+)"\n\s*asset_performance_label\b', '''[pinned_field: HEADLINE_1
    text: "5 Best Products"
    asset_performance_label: PENDING
    policy_summary_info
    {
        review_status: REVIEWED
        approval_status: APPROVED
    }
    , pinned_field: HEADLINE_1
    text: "10 Best Products 2021"
    asset_performance_label: PENDING
    policy_summary_info
    {
        review_status: REVIEWED
        approval_status: APPROVED
    }''')


print(text)

输出

['5 Best Products', '10 Best Products 2021']

【讨论】:

  • 为什么我们不需要使用`regex = re.escape(regex)`?
  • \b 是什么意思?
  • @EladBenda 我将添加模式的细分。您可以省略re.escape,因为我们创建了模式并且我们已经知道要转义什么。
  • 非常感谢。如果我想匹配(可选)pinned_field: (word) 怎么办?所以结果可能是:[`HEADLINE_1: 5 Best Products', 'HEADLINE_1:10 Best Products 2021', 'some_text_without_pinned_field'] ?
  • @EladBenda 然后您可以将第一组设为可选regex101.com/r/CFZXHp/1 并且 re.findall 将返回一个元组列表,如果没有组 1,则第一个为空。请参阅 ideone.com/MmDT1s 或者您可以使用 re.finditer 并检查组 1 的存在并连接组 ideone.com/QMAyIY
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-01
  • 2021-11-17
  • 1970-01-01
  • 2016-12-18
相关资源
最近更新 更多