【问题标题】:Upper case between a char pythonchar python之间的大写
【发布时间】:2015-06-09 08:55:04
【问题描述】:

我需要帮助如何在这样的两颗星之间获得大写。

输入:"S*t*a*r*s are every*where*"

输出:"STaRs are everyWHERE"

我的代码在这里:

def trans(s):
    x = ""
    a = False
    for j in range(len(s)):
        if s[j] == "*" or a:
            a = True
            if a:
                x += s[j].upper()
        else:
            x += s[j]
    return "".join(x.replace("*",""))

问题是我不知道循环设置回False 的位置。现在它只看到* 并将所有内容变为大写。

【问题讨论】:

  • 在星号中,'t'和'r'也改成大写字母??
  • @upaangsaxena:是的,因为他们直接追随一颗星星。
  • 这是一个非常有名的自动机。要了解答案,请查看此图片s9.postimg.org/j9qyp60e7/auto.png
  • @BhargavRao:我已经内嵌了你的图片。
  • @J.F. Sebastian Tnx 你,现在我明白了 :)

标签: python python-3.x uppercase


【解决方案1】:

注意:其他答案很好地向您展示了如何修复您的代码。这是另一种方法,一旦您学习了正则表达式,您可能会发现它更容易。

你可以使用re.sub函数。

>>> s = "S*t*a*r*s are every*where*"
>>> re.sub(r'\*([^*]*)\*', lambda m: m.group(1).upper(), s)
'STaRs are everyWHERE'

在正则表达式中* 是一个特殊的元字符,它重复前一个标记零次或多次。为了匹配文字*,您需要在正则表达式中使用\*

所以\*([^*]*)\* 正则表达式匹配每对* 块,即(*t**r**where*)和中间字符(* 块内的字符 em>) 被第 1 组捕获。

对于每个匹配,re.sub 函数会将匹配的 *..* 块替换为 string-inside-*.upper() 。即,它将对存在于* 中的字符串应用upper() 函数并将结果作为替换字符串返回。

【讨论】:

  • 并非一切都需要正则表达式。这也不能解释 OP 哪里出错了。
  • Tnx,但我刚开始有规律的体验,所以我不太喜欢他们
  • @AvinashRaj:我相信你知道,懒惰是程序员的美德。 :) 我没有投反对票,但我同意如果可以找到简单的非正则表达式解决方案,则应避免使用正则表达式,部分原因是正则表达式往往会妨碍可读性,部分原因是正则表达式解决方案不一定有效。我想这些 cmets 不是讨论这个问题的地方,但请随时在sopython Chat 中提出。
  • @PM2Ring:为什么你认为手动实现 FSM 比指定简单的正则表达式更好?
  • @PM2Ring:据我了解,您的原因是:(1)与手写 FSM 相比,正则表达式阻碍了可读性(2)正则表达式比手写 FSM 慢(3)学习循环,条件,一个简单的 FSM 而不是正则表达式。我同意(3)(它可以被认为是掌握正则表达式的先决条件)。我非常怀疑(2),除非分析器证明不是这样,并且关于(1):一旦你学会了正则表达式,\*([^*]*)\* 是表达问题的更短更清晰的方式。每个程序员都应该学习正则表达式(这并不意味着它们应该无处不在:正则表达式经常(ab)使用超出其范围)
【解决方案2】:

你需要切换你的状态;每次找到* 时,您反转函数的状态,以便在遍历文本时可以在大写和小写之间切换。

您可以使用not 轻松完成此操作;如果FalseFalsenot a 将返回 True,反之亦然:

def trans(s):
    x = ""
    a = False
    for j in range(len(s)):
        if s[j] == "*":
            a = not a  # change state; false to true and true to false
            continue  # no need to add the star to the output
        if a:
            x += s[j].upper()
        else:
            x += s[j]
    return x

每次找到* 字符时,a 就会切换;通过当时使用continue,您还可以防止将* 字符添加到输出中,因此可以完全避免replace()。对字符串的 ''.join() 调用再次生成相同的字符串,在这种情况下不需要。

这里不需要range(),你可以直接循环s。您也可以使用更好的名称:

def trans(string):
    result = ""
    do_upper = False
    for character in string:
        if character == "*":
            do_upper = not do_upper  # change state; false to true and true to false
            continue  # no need to add the star to the output
        result += character.upper() if do_upper else character
    return result

演示:

>>> def trans(string):
...     result = ""
...     do_upper = False
...     for character in string:
...         if character == "*":
...             do_upper = not do_upper  # change state; false to true and true to false
...             continue  # no need to add the star to the output
...         result += character.upper() if do_upper else character
...     return result
... 
>>> trans('S*t*a*r*s are every*where*')
'STaRs are everyWHERE'

【讨论】:

  • 为了避免依赖 CPython 优化来获得线性行为,您可以使用 result = []result.append(..) 而不是 result = ""result += ..。最后是return ''.join(result)
【解决方案3】:

这样想。每当您看到* 时,您需要在大写和原始大写之间交替。所以,在代码中实现同样的,像这样

def trans(s):
    x, flag = "", False

    # You can iterate the string object with `for`
    for char in s:

        # The current character is a `*`
        if char == "*":
            # flip the flag everytime you see a `*`.
            flag = not flag
            # Skip further processing, as the current character is `*`
            continue

        if flag:
            # If the flag is Truthy, we need to uppercase the string
            x += char.upper()
        else:
            # Otherwise add the character as it is to the result.
            x += char

    # no need to `join` and `replace`, as we already skipped `*`. So just return.
    return x

【讨论】:

    【解决方案4】:

    a 应该在TrueFalse 之间切换。您只需将其设置为True。还直接迭代字符串的字符而不是索引。并使用更全面的变量名。如果您一次跳过“*”,则不需要加入,也不需要替换:

    def trans(text):
        result = ""
        upper = False
    
        for char in text:
            if char == "*":
                upper = not upper
            elif upper:
                result += char.upper()
            else:
                result += char
        return result
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-11-05
      • 2015-07-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多