2013-04-06 87 views
2

我試圖解析從python中的GSM調制解調器接收到的消息。在python中解析GSM調制解調器接收的消息參數

我有很多消息需要解析。我每隔幾個小時收到一封新郵件。

下面是通過使用串行對象將數據從調制解調器讀入列表x後接收的數據示例。

AT+CMGL="ALL" 


+CMGL: 1,"REC READ","+918884100421","","13/04/05,08:24:36+22" 
here's message one 

+CMGL: 2,"REC READ","+918884100421","","13/04/05,09:40:38+22" 
here's message two 

+CMGL: 3,"REC READ","+918884100421","","13/04/05,09:41:04+22" 
here's message three 

+CMGL: 4,"REC READ","+918884100421","","13/04/05,10:04:18+22" 
here's message four 

+CMGL: 5,"REC READ","+918884100421","","13/04/05,10:04:32+22" 
here's message five 

. 
. 
. 
. 
. 

還有很多消息,我剛剛在這裏列出了五個。

我的主要意圖是提取消息的內容,例如「這裏是消息一」等等,我接收到的每條消息。

下面是我現在使用的代碼。

def reading(): 
    print "Reading all the messages stored on SIM card" 
    phone.write(b'AT+CMGL="ALL"\r') 
    sleeps() 
    x=phone.read(10000) 
    sleeps() 
    print x 
    print "Now parsing the message!" 
    k="".join(x) 
    parse(k) 
    k="" 
def parse(k): 
    m = re.search("\+CMGL: (\d+),""(.+)"",""(.+)"",(.*),""(.+)""\r\n(.+)\r\n",k) 
    print "6=" 
    print m.group(6) 

電話是我用來從GSM調制解調器讀取的串行對象。

這裏m.group(6)捕獲的第一條消息的消息內容「這裏的消息一個」

我怎樣才能得到它的所有消息,不只是第一個的內容相匹配。

我試着設置多行標誌,但沒有奏效。沒有使用re.findall()代替re.search()。

此外re.search返回的匹配對象不可迭代。

請幫忙。

+0

我可以問你添加接收消息的Python程序到你的問題嗎? – Abraham 2015-06-20 06:47:43

回答

1

因爲我沒有得到你的材料我只是做一個樣品。

'\xef\xbb\xbfAT+CMGL="ALL"\n\n+CMGL: 1,"REC READ","+918884100421","","13/04/05,08:24:36+22"\nhere\'s message one \n\n+CMGL: 2,"REC READ","+918884100421","","13/04/05,09:40:38+22"\nhere\'s message two\n\n+CMGL: 3,"REC READ","+918884100421","","13/04/05,09:41:04+22"\nhere\'s message three\n\n+CMGL: 4,"REC READ","+918884100421","","13/04/05,10:04:18+22"\nhere\'s message four\n\n+CMGL: 5,"REC READ","+918884100421","","13/04/05,10:04:32+22"\nhere\'s message five\n' 

這來自你的問題使用''.join()。然後我使用您的正則表達式模式,只需將\r\n替換爲\n,因爲我使用的示例使用的是\n。我得到結果。我不知道爲什麼findall不適合你。

def parse(x): 
    res = [] 
    match = re.finditer("\+CMGL: (\d+),""(.+)"",""(.+)"",(.*),""(.+)""\n(.+)\n", x) 
    for each in match: 
     res.append(each.group(6)) 
    return res 

我得到的結果是["here's message one ", "here's message two", "here's message three", "here's message four", "here's message five"]finditer返回一個迭代器,並且findall也可以正常工作。

def parse(x): 
     res = [] 
     match = re.findall("\+CMGL: (\d+),""(.+)"",""(.+)"",(.*),""(.+)""\n(.+)\n", x) 
     for each in match: 
      res.append(each[5]) 
     return res 
+0

啊,finditer!會試試看,謝謝! – Anon 2013-04-06 18:10:04

0

如果該消息始終是換行符

(?:[\n\r]+|^)\+CMGL.*?[\n\r]+(.*?)(?=[\n\r]+|$) 

1組包含您需要消息

+0

謝謝你會試試asap =) – Anon 2013-04-06 18:08:57

3

對此使用regexp不是一個非常強大的解決方案,因爲它不會處理不同的手機行爲的變化。在您的示例響應的格式是

+CMGL: 1,"REC READ","+918884100421","","13/04/05,08:24:36+22" 

但其他手機會給像

+CMGL: 1,"REC READ","+31612123738",,"08/12/22,11:37:52+04" 

公告迴應了第四參數,""對什麼區別。 檢出27.005,在文本模式下響應語法

+CMGL: <index>,<stat>,<oa/da>,[<alpha>],[<scts>][,<tooa/toda>,<length>]<CR><LF> 
<data><CR><LF> 

<alpha>確實是可選的。是的,編寫一個可以考慮這個問題的正則表達式可能是可行的,但是你可能會漫步到two problems land


我建議你做的是切換到做響應的正確解析,即:根據預期參數格式(和存在)開始以塊的第一個字符和進步。請參閱this answer以快速和骯髒的方式來提取電話號碼。它不像我在下面描述的算法那樣健壯(例如comma + 2假設太多)。

絕對正確算法解析響應是:

匹配就行(例如+CMGL:)的開始的前綴。然後開始解析區分下列標記:

  • 空白' ''\t'
  • 逗號','
  • 雙引號'"'
  • 回車'\r'
  • 換行符'\n'
  • 任何-non-white-space-non-comma-non-double-quote-non-cr-non-lf-character

對於每個參數,首先忽略任何前導空格。 如果得到一個逗號,該參數不存在,提前解析下一個參數。 如果得到回車,下一個字符應該換行,並且到達行尾。如果得到一個非空白非...字符,這是一個數字參數的開始。收集此參數後面的所有非空白非字符。在此之後,唯一的合法字符應該是零個或多個空格,後跟逗號或回車。 如果將雙引號字符提前到下一個雙引號字符,即字符串的末尾(這是安全和正確的,因爲即使字符串應該包含雙引號字符,它們也會被轉義,但不是\")。在此之後,唯一合法的字符應該是零個或多個空格,後跟逗號或回車。

剛開始時,上面的內容看起來可能有些壓倒性的,但是當你開始處理它時真的不那麼複雜。

+0

哇,這真的很有見地!將盡快測試它,看看它如何,謝謝:) – Anon 2013-04-06 18:08:28

相關問題