仅使字符串的特定部分为大写

时间:2015-07-09 21:13:30

标签: python regex

对于我的项目,我正在解析reddit注释并尝试将它们设为大写。它与纯文本完美匹配,但是如链接之类的东西会产生错误,使链接中的字符变为大写,从而使链接无法使用。现在,reddit上的链接语法非常简单,即[text](url)。我想输出[TEXT](url)知道我的评论很可能会有其他一些内容。

我尝试使用正则表达式,但这仍然不起作用,而我仍然认为我非常接近:

import re

def make_upper(comment):
    return re.sub(r"\[([^ ]*)\]\(([^ ]*)\)", r"[\1]".upper() + r"(\2)", comment)

正则表达式有点混乱(就像所有的正则表达式一样;)但我仍然可读,如果需要,我也不介意解释它。

输入:

"blablabla (btw, blargh!) [text](url) blabla"

期望的输出:

"BLABLABLA (BTW, BLARGH!) [TEXT](url) BLABLA"

3 个答案:

答案 0 :(得分:2)

这是我在进行一些实验后采用的方法。我确信如果我像对待他们一样忽略了某些事情,那么人们会对我进行投票并在评论中告诉我。

第1步:正则表达式

你几乎就在这里,但我会把它变成非贪婪,这样它就不会将由非链接文本分隔的两个链接视为一个。

MARKDOWN_LINK_REGEX = re.compile(r'\[(.*?)\]\((.*?)\)')

另外,至少对于方括号中的部分,不要假设不会有空格。人们可以根据需要链接尽可能多的单词,甚至整个句子。

第2步:功能

def uppercase_comment(comment):
    result = comment.upper()
    for match in re.finditer(MARKDOWN_LINK_REGEX, comment):
        upper_match = match.group(0).upper()
        corrected_link = upper_match.replace(match.group(2).upper(),
                                             match.group(2))
        result = result.replace(upper_match, corrected_link)
    return result

首先,将整个评论设为大写,然后进行更正。对于更正,我循环上面的正则表达式生成的所有非重叠匹配(re.finditer),通过小写括号中的内容来修复链接,然后使 >替换原始注释字符串。 正如评论中指出的那样,小写链接并不总是有效 - 必须保留原始案例。在更新的函数中,我们循环原始注释中的匹配(以及原始案例)以生成替换,将其添加到我们在开头创建的大写字符串。

第3步:测试出来

if __name__ == '__main__':
    print(uppercase_comment('this comment has zero links'))
    print(uppercase_comment('this comment has [a link at the end](Google.com)'))
    print(uppercase_comment('[there is a link](Google.com) at the beginning'))
    print(uppercase_comment('there is [a link](Google.com) in the middle'))
    print(uppercase_comment('there are [a few](Google.com) links [in](StackOverflow.com) this one'))
    print(uppercase_comment("doesn't matter (it shouldn't!) if there are [extra parens](Google.com)"))

可生产

THIS COMMENT HAS ZERO LINKS
THIS COMMENT HAS [A LINK AT THE END](Google.com)
[THERE IS A LINK](Google.com) AT THE BEGINNING
THERE IS [A LINK](Google.com) IN THE MIDDLE
THERE ARE [A FEW](Google.com) LINKS [IN](StackOverflow.com) THIS ONE
DOESN'T MATTER (IT SHOULDN'T!) IF THERE ARE [EXTRA PARENS](Google.com)

请评论反馈和修正。注意我的是Python 3,但我使用的唯一具体的3是打印功能。

答案 1 :(得分:2)

感谢大家,这里是您所有建议的组合版本,可以完成我想要的所有内容:

def make_upper(comment):
    native_links = re.findall(r"\[.*?\]\((.*?)\)", comment)
    result = comment.upper()
    for url in native_links:
        result = result.replace(url.upper(), url)
return result

我不太确定它是最快的方法,但在最终的算法中,这段代码不应该经常使用,以便再次使用,谢谢!

答案 2 :(得分:2)

之前的答案依赖全局搜索和替换来处理解决方案。对于链接的URL也包含在文本的其余部分中的情况,这是有缺陷的。保证安全的方法是在你进行时构造新的字符串。

例如,虽然这不是优雅的,但它可以解决问题:

MARKDOWN_LINK_REGEX = re.compile(r'(.*?)(\[.*?\])(\(.*?\))(.*)')

def uppercase_comment(text):
    result = ""
    while True:
        match = MARKDOWN_LINK_REGEX.match(text)
        if match:
            result += match.group(1).upper() + match.group(2).upper()
            result += match.group(3)
            text = match.group(4)
        else:
            result += text.upper()
            return result