【问题标题】:What is the best method of processing optional group in Python Regex?在 Python Regex 中处理可选组的最佳方法是什么?
【发布时间】:2020-05-12 05:00:57
【问题描述】:

我正在尝试编写一个函数来强制某些单词大写,并在某些单词后面加上“s”时添加“s”。例如,它应该采用 Grace 并将其转换为 Grace 的。

r"(\b)(grace)( (s|S))?\b": posessive_name,

{...}

def possessive_name(match: Match) -> str:
    result = match.group(2).title()
    result = result.replace(" ", "'")
    return result  # type: ignore

我正确地“命名”了它,但不知道如何引用可选的 ( (s|S)) 组,以便在需要时添加 ( 's),我想避免添加额外的正则表达式......这可能吗?

*为清晰起见编辑了名称

【问题讨论】:

    标签: python regex nlp


    【解决方案1】:

    是的,像这样。

    import re
    
    test_str = "This is grace s apple."
    
    def fix_names(match):
        name, s = match.groups()
        name = name.title()
        if s:
            name = f"{name}'s"
        return name
    
    p = re.compile(r"\b(grace)(\s[sS])?\b")
    print(p.sub(fix_names, test_str))
    

    【讨论】:

      【解决方案2】:
      lines = (
          'a grace s apple',
          'the apple is grace s',
          'take alice s and steve s',
      )
      for line in lines:
          result = re.sub(r'(\w+)\s+s($|\s)', lambda m: m.group(1).title()+"'s"+m.group(2), line, flags=re.I|re.S)
          print(result)
      

      你会得到:

      格蕾丝的苹果

      苹果是格蕾丝的

      拿 Alice 和 Steve 的

      【讨论】:

        【解决方案3】:

        您可以在第 1 组中捕获 1+ 个单词字符,然后使用 character class 匹配空格和 s 或 S。

        在替换中使用组 1 上的 .title() 并添加 's

        (?<!\S)(\w+) [sS](?!\S)
        

        解释

        • (?&lt;!\S)左空白边界
        • (\w+)捕获组1,匹配1+字字符
        • [sS] 匹配空格和s 或S
        • (?!\S)

        Regex demo | Python demo

        代码示例

        import re
        test_str = "grace s"
        regex = r"(?<!\S)(\w+) [sS](?!\S)"
        result = re.sub(regex, lambda match: match.group(1).title()+"'s", test_str)
        print(result)
        

        输出

        Grace's
        

        如果您想专门匹配 grace,您可以使用可选组。如果你想匹配更多的单词,你可以使用(?:grace|anotherword)

        (?<!\S)(grace)(?: ([sS]))?\b
        

        Regex demo

        示例代码

        import re
        test_str = "Her name is grace."
        strings = [
            "grace s",
            "Her name is grace."
        ]
        pattern = r"(?<!\S)(grace)(?: ([sS]))?\b"
        regex = re.compile(pattern)
        
        for s in strings:
            print(
                regex.sub(
                    lambda m: "{}{}".format(m.group(1).title(), "'s" if m.group(2) else '')
                    , s)
            )
        

        输出

        Grace's
        Her name is Grace.
        

        【讨论】:

        • 从 OP 中,如果某些单词后跟“s”,则将“'s”添加到它们。该函数需要能够处理也没有 s 的情况
        • @nicholishen 您好,问题是and adds "'s" to certain words if they are followed by " s",所以我认为应该有一个空格。在 OP 的模式中也有一个空格。请注意,\s 匹配空白字符,也可以匹配不同于空格的换行符。
        • 您需要添加以下测试。 “她的名字叫恩典。”它应该附加一个 '。
        • 如果是专门为了优雅,我又加了一个选项。
        • 你可以稍微简化一下 lambda...lambda m: "{}{}".format(m.group(1).title(), "'s" if m.group(2) else '')
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-09-06
        • 2011-09-16
        • 2011-01-13
        相关资源
        最近更新 更多