-1

这是一个奇怪的:

我正在尝试在 python 中格式化一个字符串(显然),当我使用 时string.title(),似乎 python 一直在对字符串应用标题大小写,即使在对字符串应用其他格式之后也是如此。

这是我的代码:

    def format_trade_name(self):
        tr_name = self.trade_name.title()
        tr_cap = [
            'oxy',
            'depo',
            'edex',
            'emla',
            'pred',
        ]
        tr_join = '|'.join(tr_cap)   
        tr_regex = r'\b(?!(' +tr_join + r'))(\w{1,4})\b'
        tr_matches = re.search(tr_regex, self.trade_name,re.IGNORECASE)
        for i in tr_matches.groups():
            if i is not None:
                tr_name = re.sub(r'\b'+i+r'\b',i.upper(),tr_name)
        return tr_name

这就是问题所在: 我希望函数将每个单词的第一个字母大写,然后将所有 4 个字母字符串(不在 tr_cap 中)转换为大写。所以如果原始字符串是tylenol depo er,我希望格式化的字符串是Tylenol Depo ER

当我将第 2 行更改为 时tr_name = self.trade_name.capitalize(),我的函数tylenol depo er变为Tylenol depo ER(depo未大写)。

当我将第二行保持原样时tr_name = self.trade_name.title(),我的函数变为tylenol depo er(Tylenol Depo Er不是Er大写,即使在使用 .title() 后应用了格式。

任何人都可以向我解释为什么字符串被转换为标题大小写,即使在我尝试应用新格式之后?

更新 所以我修复了它,但我不知道它为什么会起作用。我觉得我缺少一些重要的原则。

当我改变tr_matches = re.search(tr_regex, self.trade_name,re.IGNORECASE)它的tr_matches = re.search(tr_regex, tr_name, re.IGNORECASE)工作。

所以,这有效:

    def format_trade_name(self):
        tr_name = self.trade_name.title()
        tr_cap = [
            'oxy',
            'depo',
            'edex',
            'emla',
            'pred',
        ]
        tr_join = '|'.join(tr_cap)   
        tr_regex = r'\b(?!(' +tr_join + r'))(\w{1,4})\b'
        tr_matches = re.search(tr_regex, tr_name ,re.IGNORECASE)
        for i in tr_matches.groups():
            if i is not None:
                tr_name = re.sub(r'\b'+i+r'\b',i.upper(),tr_name)
        return tr_name

任何想法为什么?

4

1 回答 1

1

您没有在整个函数中使用标题大小写的字符串:

tr_matches = re.search(tr_regex, self.trade_name,re.IGNORECASE)

这些匹配项将是小写,但您的 re.sub 正在搜索混合大小写的字符串。

将代码切换为:

tr_matches = re.search(tr_regex, tr_name, re.IGNORECASE)

编辑:如果你想大写多个子字符串, re.search 不会做,因为它只匹配一个。findall 应该可以解决问题,例如:

tr_matches = re.findall(tr_regex, self.trade_name,re.IGNORECASE)
print(tr_matches)
for _, i in tr_matches:
    if i is not None:
        tr_name = re.sub(r'\b'+i+r'\b',i.upper(),tr_name)
        print(tr_name)

编辑 2: re.sub() 足够灵活,您可以删除整个匹配步骤和循环。它可以使用 lambda 函数匹配每个 1-4 位单词并将它们大写:

  def format_trade_name(self):
        tr_name = self.trade_name.capitalize()
        tr_cap = [
            'oxy',
            'depo',
            'edex',
            'emla',
            'pred',
        ]
        tr_join = '|'.join(tr_cap)   
        tr_regex = r'\b(?!' +tr_join + r')(\w{1,4})\b'

        tr_name = re.sub(
            tr_regex,
            lambda match: match.group(0).upper(), 
            tr_name
        )
        return tr_name
于 2021-03-29T21:07:04.127 回答