2013-04-06 88 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

相关问题