2015-01-21 75 views
-1

嘿,我需要創建簡單的python隨機數發生器。例如輸入:python隨機數發生器 - 在雙層嵌套級別的大括號​​中獲得隨機文本

{{hey|hello|hi}|{privet|zdravstvuy|kak dela}|{bonjour|salut}}, can {you|u} give me advice? 

和輸出應該是:

hello, can you give me advice 

我有一個腳本,它可以做到這一點,但只有一層嵌套

with open('text.txt', 'r') as text: 
    matches = re.findall('([^{}]+)', text.read()) 
words = [] 
for match in matches: 
    parts = match.split('|') 
    if parts[0]: 
     words.append(parts[random.randint(0, len(parts)-1)]) 
message = ''.join(words) 

這是不夠的,我)

+0

對我而言,似乎你的輸入遵循的語法對於簡單的正則表達式有點複雜。我會說,構建一個適當的詞法分析器,由分析器調用以產生輸出。如果你不熟悉這個概念,我建議你先閱讀理論:) – 2015-01-21 11:28:34

+1

你正在尋找遞歸正則表達式匹配。見:http://stackoverflow.com/questions/1656859/how-can-a-recursive-regexp-be-implemented-in-python – 2015-01-21 11:29:30

+0

@ KarelKubat哦,不,我不需要這個。我只想從大括號中得到隨機文本,其中包含另一個大括號 – 2015-01-21 11:29:57

回答

2

Python的正則表達式不支持嵌套結構,所以你必須找到一些其他的方式來解析st環。

這裏是我的快速雜牌組裝電腦:

def randomize(text): 
    start= text.find('{') 
    if start==-1: #if there are no curly braces, there's nothing to randomize 
     return text 

    # parse the choices we have 
    end= start 
    word_start= start+1 
    nesting_level= 0 
    choices= [] # list of |-separated values 
    while True: 
     end+= 1 
     try: 
      char= text[end] 
     except IndexError: 
      break # if there's no matching closing brace, we'll pretend there is. 
     if char=='{': 
      nesting_level+= 1 
     elif char=='}': 
      if nesting_level==0: # matching closing brace found - stop parsing. 
       break 
      nesting_level-= 1 
     elif char=='|' and nesting_level==0: 
      # put all text up to this pipe into the list 
      choices.append(text[word_start:end]) 
      word_start= end+1 
    # there's no pipe character after the last choice, so we have to add it to the list now 
    choices.append(text[word_start:end]) 
    # recursively call this function on each choice 
    choices= [randomize(t) for t in choices] 
    # return the text up to the opening brace, a randomly chosen string, and 
    # don't forget to randomize the text after the closing brace 
    return text[:start] + random.choice(choices) + randomize(text[end+1:]) 
+0

哦,謝謝你!) – 2015-01-21 12:47:26

1

正如我前面所說,嵌套基本上是無用的在這裏,但如果你想保持你當前的語法,來處理它的方法之一是更換一個循環括號直到沒有更多:

import re, random 

msg = '{{hey|hello|hi}|{privet|zdravstvuy|kak dela}|{bonjour|salut}}, can {you|u} give me advice?' 


while re.search(r'{.*}', msg): 
    msg = re.sub(
     r'{([^{}]*)}', 
     lambda m: random.choice(m.group(1).split('|')), 
     msg) 

print msg 
# zdravstvuy, can u give me advice?