【问题标题】:If you are really good at Python and Regex, please help fix function如果你真的很擅长 Python 和 Regex,请帮助修复函数
【发布时间】:2010-02-20 00:39:51
【问题描述】:
def boldword(text, needle):
    return mark_safe(re.compile(r"\b(%s)\b" % "|".join(map(re.escape, needle.split(' '))), re.I).sub(r'<strong>\1</strong>', text))

这是我目前的功能,在给定针的情况下将字符串文本加粗。 (就像 Google...当您进行搜索时,它们会为您将文本加粗)。

  • 当指针是“节目”时,它不会突出显示“www.theshow.com”。
  • 当指针是“我的节目(视频)”时,它不会突出显示“我的节目(视频)”...它只会突出显示我的节目
  • 当针是“apple's ipad”时,它不会高​​亮“apple ipad”……它只会高亮ipad。

    预期输出: www.theshow.com ,电流输出: www.theshow.com

    预期输出: 我的节目(视频) ,电流输出: 我的节目(视频)

    预期: 苹果ipad ,当前的: 苹果ipad

我认为主要问题是当我将空格与其他标点符号分开时。正确的? 有人可以修改我当前的功能以考虑这些因素吗?

谢谢

【问题讨论】:

  • 我认为你应该用 Lisp 写作!
  • 您给出的输出示例是您的预期输出还是您观察到的输出?如果是您观察到的输出,您的预期输出是什么?
  • 示例是我的预期输出。我会编辑清楚。
  • 所以应该可以组合词吧?不连续的词怎么办?例如:boldword('a b c', 'ac')... 'ac' 是否应该加粗?
  • 我认为您需要更好地解释您想要什么,或者提供超过 3 个参考示例。

标签: python regex


【解决方案1】:

您最大的问题似乎是单词边界。如果您要搜索的标记可以以非单词字符开头或结尾(例如,(video)),则将正则表达式括在 \b 中会阻止匹配。它们还阻止匹配两个或多个连续标记(例如,www.theshow.com 中的 theshow)。但是,与其丢失单词边界,我建议您忽略搜索表达式中的标点符号并构造正则表达式以便一次匹配一个或多个标记:

re.compile(r"\b((?:%s)+)\b" % "|".join(re.split(r"\W+", needle)), re.I)

/\W+/ 上拆分会删除所有标点符号和空格,因此无需转义任何内容。我的结果似乎与您想要的结果相匹配,除了 (video) 中的括号没有突出显示,只有单词 video 是。如果搜索表达式是"the show",它会突出显示www.theshow.com 中的theshow,但不会突出显示www.footheshowbar.com

【讨论】:

    【解决方案2】:

    您的描述告诉我的是 A) 输入变量没有正确地被空格分割,B) 它没有被正确转义。

    我认为这可能是括号内表达式的一个实例:

    试试这个:

    return mark_safe(re.compile((r"\b(%s)\b" % ("|".join(map(re.escape, needle.split(' '))), re.I))).sub(r'<strong>\1</strong>', text))
    

    【讨论】:

    • 推荐多括号是残忍的。
    【解决方案3】:

    这是我添加的一些胶带,以帮助您通过您列出的案例 - 这个问题实际上很有趣。可能有些情况不正确(例如,如果您搜索 ducks,Google 会突出显示 duck,这仅适用于 duck's)。

    如果没有一套更通用的指导方针,很难编写一个涵盖所有情况的正则表达式 - 但取决于您需要它有多接近最终将决定您需要使其复杂程度。

    import re, string
    
    def boldword(text,needle):
        n = re.sub('[%s]s*' % re.escape(string.punctuation), '', needle)
        patterns = map(re.escape, n.split(' '))
        patterns.append(n.replace(' ', ''))
        regex = re.compile(r"\b(%s)\b" % '|'.join(patterns), re.I)
        match = re.match(regex, text.replace(' ',''))
        if match:
            return "<strong>%s</strong>" % text
        return re.sub(regex, r'<strong>\1</strong>', text)
    
    print boldword("www.theshow.com", "the show")
    print boldword("my show (video)", "my show (video)")
    print boldword("apple ipad", "apple's ipad")
    print boldword("stack overflow", "stackoverflow")
    

    输出

    >> www.<strong>theshow</strong>.com
    >> <strong>my</strong> <strong>show</strong> (<strong>video</strong>)
    >> <strong>apple ipad</strong>
    >> <strong>stack overflow</strong>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-10-31
      • 1970-01-01
      • 2019-03-26
      • 2017-08-07
      • 2022-12-01
      • 1970-01-01
      • 2011-05-27
      相关资源
      最近更新 更多