2013-03-11 45 views
1

我想讓程序讓我們說,如果我的word_str是「這是'劍橋大學'例如。」如果單詞的長度大於3個字符,它將保留單詞的第一個和最後一個字母,並將單詞的內部加擾。我的問題是,它不正確地在單詞的開頭或結尾處用標點符號混淆單詞。我需要它來洗牌,以便標點符號保留在正確的索引中,然後保留單詞的第一個和最後一個字母,並在最後添加標點的單詞的內部進行混洗(如果有的話)。有任何想法嗎?如何從字符串中剝離標點符號,然後將其添加回相同的索引中?

def scramble_word(word_str): 
char = ".,!?';:" 
import random 
if len(word_str) <= 3: 
    return word_str + ' ' 
else: 
    word_str = word_str.strip(char) 
    word_str = list(word_str) 
    scramble = word_str[1:-1] 
    random.shuffle(scramble) 
    scramble = ''.join(scramble) 
    word_str = ''.join(word_str) 
    new_word = word_str[0] + scramble + word_str[-1] 
    return new_word + ' ' 
+0

爲什麼而忽略了標點符號不搶就在信嗎? – 2013-03-11 22:15:36

+0

因爲程序規範要求我不要忽略標點符號 – Tyler 2013-03-11 22:25:42

+0

但是如果你要把它放回**與以前的爭奪,這實質上完全模仿忽略它的結果,同時加擾字母數字字符。或者我錯過了什麼? – 2013-03-11 22:28:00

回答

5

使用正則表達式:

import random 
import re 

random.seed(1234) #remove this in production, just for replication of my results 

def shuffle_word(m): 
    word = m.group() 
    inner = ''.join(random.sample(word[1:-1], len(word) - 2)) 
    return '%s%s%s' % (word[0], inner, word[-1]) 

s = """This is 'Cambridge University' for example.""" 

print re.sub(r'\b\w{3}\w+\b', shuffle_word, s) 

它打印

Tihs is 'Cadibrgme Uinrtvsiey' for exlampe. 

re.sub允許你通過它的功能(它接受一個正則表達式匹配對象),而不是替換字符串。

編輯 - 無正則表達式

from StringIO import StringIO 

def shuffle_word(m): 
    inner = ''.join(random.sample(m[1:-1], len(m) - 2)) 
    return '%s%s%s' % (m[0], inner, m[-1]) 

def scramble(text) 
    sio = StringIO(text) 
    accum = [] 
    start = None 
    while sio.tell() < sio.len: 
     char = sio.read(1) 
     if start is None: 
      if char.isalnum(): 
       start = sio.tell() - 1 
      else: 
       accum.append(char) 
     elif not char.isalnum(): 
      end = sio.tell() - 1 
      sio.seek(start) 
      accum.append(shuffle_word(sio.read(end - start))) 
      print accum[-1] 
      start = None 
    else: 
     if start is not None: 
      sio.seek(start) 
      word = sio.read() 
      if len(word) > 3: 
       accum.append(shuffle_word(sio.read())) 
      else: 
       accum.append(word) 

    return ''.join(accum) 

s = """This is 'Cambridge University' for example.""" 
print scramble(s) 
+0

一個不錯的解決方案。會建議使用re.split()分割文本,並在通過scramble_word傳遞單詞之後重新組合它,但將函數傳遞給re.sub則更加優雅。 – CaptSolo 2013-03-11 22:32:59

+0

你怎麼能沒有re.sub? – Tyler 2013-03-11 22:52:39

+0

@MikePang:你的意思是沒有特定的're.sub',或者沒有一般的正則表達式? – 2013-03-11 22:53:42

1

的極端易於使用正則表達式:

import re 
import random 

s = ('Pitcairn Islands, Saint Helena, ' 
    'Ascension and Tristan da Cunha, ' 
    'Saint Kitts and Nevis, ' 
    'Saint Vincent and the Grenadines, Singapore') 

reg = re.compile('(?<=[a-zA-Z])[a-zA-Z]{2,}(?=[a-zA-Z])') 

def ripl(m): 
    g = list(m.group()) 
    random.shuffle(g) 
    return ''.join(g) 

print reg.sub(ripl,s) 

結果

Piictran Islands, Sanit Heelna, Asnioecsn and Tiastrn da Cunha, Sniat Ktits and Neivs, Snait Vnnceit and the Giearndens, Snoiaprge 
相關問題