C#使用正则表达式提取GPS信息

来源:互联网 发布:教孩子学编程 编辑:程序博客网 时间:2024/05/10 21:29

用过GPS模块的人应该知道,该模块间隔1s返回GPS信息,格式是NEMA-0183标准格式,一般我们是通过串口读入字符串,然后对字符串进行处理得到经纬度信息,这里的字符串处理主要就是字符串分割函数(C#语言中对应于string.Split()函数),比如需要先按$进行分割得到很多行,对于某一行再按,分割得到各个信息字符串数组,最后用指针进行判断查找,这样的过程显然比较复杂,而且指针用错了还会报错。

有了正则表达式,查找就比较容易了。

这里我需要提取的是$GPGGA这一行里面的经纬度信息,正则表达式为

newRegex("^\\$GPGGA.*,(\\d{4}.\\d{4}),N.*,(\\d{5}.\\d{4}),E",RegexOptions.Multiline)

具体代码如下:

class Program
    {
        public static string yyy = @"$GPGGA,235946.065,0000.0000,N,00000.0000,E,0,00,,0.0,M,0.0,M,,0000*4F
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPRMC,235946.065,V,0000.0000,N,00000.0000,E,,0.00,140209,,,N*6A
$GPTXT,01,01,02,ANTSTATUS=OK*3B
$RTOEM,1,0*40
$GPGGA,235947.073,0000.0000,N,00000.0000,E,0,00,,0.0,M,0.0,M,,0000*49
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGGA,131042.000,3031.8045,N,11421.3421,E,1,07,1.0,40.4,M,-13.9,M,,0000*42
$GPGSA,A,3,18,15,29,09,21,05,26,,,,,,2.6,1.0,2.4*3C
$GPRMC,131042.000,A,3031.8045,N,11421.3421,E,0.00,0.00,261011,,,A*65
$GPGGA,131043.000,3031.8045,N,11421.3421,E,1,07,1.0,40.4,M,-13.9,M,,0000*43
$GPGSA,A,3,18,15,29,09,21,05,26,,,,,,2.6,1.0,2.4*3C
$GPRMC,131043.000,A,3031.8045,N,11421.3421,E,0.00,0.00,261011,,,A*64
$GPGGA,131044.000,3031.8045,N,11421.3421,E,1,07,1.0,40.4,M,-13.9,M,,0000*44
$GPGSA,A,3,18,15,29,09,21,05,26,,,,,,2.6,1.0,2.4*3C
$GPRMC,131044.000,A,3031.8045,N,11421.3421,E,0.00,0.00,261011,,,A*63
$GPGGA,131045.000,3031.8045,N,11421.3421,E,1,07,1.0,40.4,M,-13.9,M,,0000*45
$GPGSA,A,3,18,15,29,09,21,05,26,,,,,,2.6,1.0,2.4*3C
$GPRMC,131045.000,A,3031.8045,N,11421.3421,E,0.00,0.00,261011,,,A*62
$GPGGA,131046.000,3031.8045,N,11421.3421,E,1,07,1.0,40.4,M,-13.9,M,,0000*46
$GPGSA,A,3,18,15,29,09,21,05,26,,,,,,2.6,1.0,2.4*3C
$GPGSV,2,1,08,15,71,358,42,21,45,312,44,09,38,166,44,26,36,037,33*7C
$GPGSV,2,2,08,18,29,301,40,05,27,081,33,29,25,226,40,02,05,143,*73
$GPRMC,131046.000,A,3031.8045,N,11421.3421,E,0.00,0.00,261011,,,A*61";

        static void Main(string[] args)
        {
            MatchCollection mc;
          
            //$GPGGA,<1>,<2>,<3>,<4>,<5>,<6>,<7>,<8>,<9>,M,<10>,M,<11>,<12>*xx<CR><LF>
            //<1>~<5>的格式为$GPGGA,hhmmss.sss,ddmm.mmmm,N/S,dddmm.mmmm,E/W,
            //<6> GPS状态, 0未定位, 1非差分定位, 2差分定位, 3无效PPS, 6正在估算
            //<7> 使用卫星数量,从00到12(第一个零也将传送)
          //<8> 水平精确度,0.5到99.9
          //<9> 天线离海平面的高度,-9999.9到9999.9米
          //M 指单位米
          //<10> 大地水准面高度,-9999.9到9999.9米
          //M 指单位米
            Regex r2 = new Regex("^\\$GPGGA.*,(\\d{4}.\\d{4}),N.*,(\\d{5}.\\d{4}),E", RegexOptions.Multiline); //定义一个Regex对象实例
            mc = r2.Matches(yyy);

            Console.WriteLine("\nsearch " + r2.ToString() + " in " + yyy + '\n');
            for (int i = 0; i < mc.Count; i++) //显示匹配结果
            {
                Match match = mc[i];
                for (int j = 0; j < match.Groups.Count; j++)
                {
                     Console.WriteLine("Groups[{0}]={1}", j, match.Groups[j].Value);        
                }
                Console.WriteLine(mc[i].Value + "\t" + mc[i].Index.ToString() + '\n'); //显示匹配的字符串和记录匹配字符的位置     
            }
            while (1 > 0) ;
        }
    }

运行结果如下


其中Group[1],Group[2]为纬度和经度信息

 

注:1. 有些GPS模块的$GPGGA后面的经纬度格式不一样,如ublox公司的TTL-LEA-5H/5S/5A的经纬度格式小数点后多一位,这是需要稍微修改正则表达式,将"^\\$GPGGA.*,(\\d{4}.\\d{4}),N.*,(\\d{5}.\\d{4}),E"改为"^\\$GPGGA.*,(\\d{4}.\\d{4,5}),N.*,(\\d{5}.\\d{4,5}),E"即可兼容两种模块。

2. 对于C#中的长字符串常量的定义,可以在前面加@即可在字符串数据里面输入换行符,当然也可以用一个字符串+另一个字符串处理这种问题。
3. 后来自己使用正则表达式的时候老是忘了怎么用了,要查半天,这里对newRegex("^\\$GPGGA.*,(\\d{4}.\\d{4}),N.*,(\\d{5}.\\d{4}),E",RegexOptions.Multiline)做一点解释,也让自己有点思路。这句话的意思是创建一个可以多行搜索的正则表达式,考虑到string对\\的转义实现,^\\$GPGGA.*,(\\d{4}.\\d{4}),N.*,(\\d{5}.\\d{4}),E其实就是^\$GPGGA.*,(\d{4}.\d{4}),N.*,(\d{5}.\d{4}),E,即以$GPGGA开头(^是以什么开头的意思,而$由于已经用作以什么结束的标志,所以这里加上\表示这是一个$字符而不是某个标志).*,表示然后接多个字符(其中.表示任意字符*表示任意个.)并以,结束,接下来的()表示可以进行多个匹配,因为默认的是匹配某一行(对应mc.Groups[0]),加了()就可以在代码中mc.Groups[1]找到对()中的匹配,\d{4}表示4个数字,其中\d\digit的意思,{4}表示有四个数字,再后面的.就是一个.,其他的依次类推,后面的第二个括号对应于mc.Groups[2]。
4.关于转义字符\,假如要搜索一个以\\开头的字符串,正则表达式应该是“^\\\\\\\\”,这里有八个\,因为字符串的转义,实际上正则表达式只有4个\,而\也是正则表达式的特殊字符,所以在正则表达式中两个\才表示一个\字符,所以这里需要8个\,这里我的意思是强调多层转义带来的问题。


参考网址:

     C#中利用正则表达式实现字符串搜索,

http://www.yesky.com/top/389/2036889.shtml

     正则表达式点滴,

 http://www.189works.com/article-41695-1.html



原创粉丝点击