2015-04-04 19 views
3

我需要幫助如何在這樣的兩顆星之間得到大寫字母。字符python之間的大寫

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

OUTPUT:"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。現在它只看到*並使所有內容都成爲大寫。

state machine

+0

在星號中,'t'和'r'也改爲大寫字母? – 2015-04-04 12:08:46

+0

@upaangsaxena:是的,因爲他們直接追隨星星。 – 2015-04-04 12:10:02

+0

現在它清楚:) – 2015-04-04 12:13:59

回答

4

您需要toggle您的狀態;每當你找到一個*反轉你的函數的狀態,以便您可以在遍歷文本時在大寫和小寫之間切換。

你可以用not最簡單的做到這一點; not a將返回True如果是False,反之亦然:

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' 
+0

爲了避免依賴CPython優化來獲得線性行爲,可以使用'result = []'和'result.append(..)'而不是'result =「」'和'result + = ..'。並在最後「返回」'.join(result)'。 – jfs 2015-04-04 15:35:46

5

注:其他的答案不向你展示如何解決你的代碼了很好的工作。這是另一種方法,一旦你學習正則表達式,你會發現它更容易。

您可以使用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*)和相匹配的在其之間的字符(存在於*塊內部字符)由組1

捕獲對於每一個匹配,re.sub函數將替換匹配的*..*塊與string-inside-*.upper()。即它將對*中存在的字符串應用upper()函數,並返回結果作爲替換字符串。

+5

並非所有事情都需要正則表達式。這並不能解釋OP在哪裏出錯。 – 2015-04-04 12:11:27

+0

Tnx,但我剛開始定期擴大,所以我不善於與他們 – Hybr1d 2015-04-04 12:12:51

+0

替代品很好,但你並沒有真正回答這個問題。 – 2015-04-04 12:18:48

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 
3

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 
相關問題