每天进步一点点

[转载]正则表达式和sscanf

上一篇 / 下一篇  2012-08-04 21:55:02 / 个人分类:性能/LoadRunner

出处:http://blog.csdn.net/phil2036/archive/2009/05/27/4221704.aspx

在看这篇文章之前建议你先了解一下什么是正则表达式,具体不重复了

      好了,具体说说sscanf的这个扩展功能吧(暂且这么叫)。sscanf提供的这个扩展功能其实并不能真正称为正则表达式,因为他的书写还是离不开%,而且也很局限。但是作为处理我上面说的url已经是绰绰有余了。sscanf的这个扩展功能支持[]表示支付范围,{}表示重复次数,^表示取非,*表示跳过。所以上面这个url的解析可以写成下面这个样子:

char url[] = "dv://192.168.1.253:65001/1/1"

sscanf(url,"%[^://]%*c%*c%*c%[^:]%*c%d/%d/%d",protocol,ip,&port,&chn,&type);//这里的参数需要传地址进去。这里面port等整型的声明为int prot...

解释一下

先取得一个最长的字符串,但不包括字串://,于是protocol="dv\0";

然后跳过三个字符(%*c),其实就是跳过://

接着取一个字符串不包括字符串:,于是ip=192.168.1.253,这里简化处理了,IP就当个字符串来弄,而且不做检查

然后跳过冒号取端口到port,再跳过/取通道号到chn,再跳过/取码流类型到type。

      是不是觉得还不过瘾?我也觉得,接着举例。

sscanf("Phil\nChang","%[^\n]%*c%s",first_name,last_name);

解释:跳过一个换行符,取first_name和last_name

  sscanf("Phil\nChang","%[^\n]%*c%s",str,str1);

//str = Phil str1 = Chang
   sscanf("phil2360@gmail.com","%[^@]%*c%s",str,str1);

//str = phil2360  str1 = gmail.com

sscanf("phil2360@gmail.com","%[^@]@%s",str,str1);

//str = phil2360  str1 = gmail.com

      基本上,这个东西用的不多,但是有时候很实用,让你的代码会很简洁,但是相比正则表达式,功能又显得简陋很多,怎么用,就看个人而定了,还是那句话,不是很确定这东西是不是ANSI的,所以不考虑移植又觉得很简洁那么用吧,考虑移植那么请三思,至于正则表达式,用regex或者boost库吧,哦,我说的是C++,C#本来就带了的!

本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/phil2036/archive/2009/05/27/4221704.aspx

以下转自chinaunix:

原文地址:http://blog.chinaunix.net/u/21684/showart_499274.html

头文件 #include(stdio.h)

定义函数 int sscanf (const char *str,const char * format,........);

函数说明 sscanf()会将参数str的字符串根据参数format字符串来转换并格式化数据。格式转换形式请参考scanf()。转换后的结果存于对应的参数内。

返回值 成功则返回参数数目,失败则返回-1,错误原因存于errno中。

周星星的代码:

#include<stdio.h>

intmain()
{
      constchar*s="iios/12DDWDFF@122";
      charbuf[20];

      sscanf(s,"%*[^/]/%[^@]",buf);
      printf("%s\n",buf);

      return0;
}

结果为:12DDWDFF

sscanf与scanf类似,都是用于输入的,只是后者以屏幕(stdin)为输入源,前者以固定字符串为输入源。



%[a-z] 表示匹配a到z中任意字符,贪婪性(尽可能多的匹配)

%[aB'] 匹配a、B、'中一员,贪婪性

%[^a] 匹配非a的任意字符,贪婪性

1.常见用法。

以下是引用片段:
  charstr[512]={0};
  sscanf("123456","%s",str);

  2.取指定长度的字符串。如在下例中,取最大长度为4字节的字符串。
以下是引用片段:
  sscanf("123456","%4s",str);
//str = 1234
  3.取到指定字符为止的字符串。如在下例中,取遇到空格为止字符串。
  sscanf("123456abcdedf","%[^ ]",str);
 //str = 123456abcdedf

  4.取仅包含指定字符集的字符串。如在下例中,取仅包含1到9和小写字母的字符串。
  sscanf("123456abcdedfBCDEF","%[1-9a-z]",str);
 //str = 123456abcdedf


  5.取到指定字符集为止的字符串。如在下例中,取遇到大写字母为止的字符串。
  sscanf("123456abcdedfBCDEF","%[^A-Z]",str);
  //str = 123456abcdedf

搜集一些特殊用法:

%[]的用法:%[]表示要读入一个字符集合,如果[后面第一个字符是”^”,则表示反意思。

  []内的字符串可以是1或更多字符组成。空字符集(%[])是违反规定的,可导致不可预知的结果。%[^]也是违反规定的。
          

%[a-z]读取在 a-z 之间的字符串,如果不在此之前则停止,如

chars[]=
"hello, my friend” ; // 注意: ,逗号在不 a-z之间

 sscanf( s, “%[a-z]”, string ) ; // string=hello

%[^a-z] 读取不在 a-z 之间的字符串,如果碰到a-z之间的字符则停止,如

 char s[]="
HELLOkitty”;
// 注意: ,逗号在不 a-z之间

sscanf(s,%[^a-z],string);
// string=HELLO



%*[^=]前面带*号表示不保存变量。跳过符合条件的字符串。

              chars[]="notepad=1.0.0.1001";

       charszfilename[32]="";

       inti=sscanf(s,"%*[^=]",szfilename);

// szfilename=NULL,因为没保存

inti=sscanf(s,"%*[^=]=%s",szfilename);

// szfilename=1.0.0.1001

%40c 读取40个字符

%[^=]读取字符串直到碰到’=’号,’^’后面可以带更多字符,如:
              chars[]="notepad=1.0.0.1001";
              charszfilename[32]="";
            inti=sscanf(s,"%[^=]",szfilename);

          // szfilename=notepad

如果参数格式是:%[^=:],那么也可以从 notepad:1.0.0.1001读取notepad


sscanf( "notepad=1.0.0.1001", "%*[^=]", str );

//str =
sscanf( "notepad=1.0.0.1001", "%[^=]", str );

//str = notepad

sscanf( "notepad=1.0.0.1001", "%*[^=]=%s", str );

//str = 1.0.0.1001
sscanf( "notepad=1.0.0.1001", "%*[^=]%s", str );

//str = =1.0.0.1001

总结:%[]有很大的功能,但是并不是很常用到,主要因为:

1、许多系统的scanf函数都有漏洞. (典型的就是TC在输入浮点型时有时会出错).

2、用法复杂,容易出错.

3、编译器作语法分析时会很困难,从而影响目标代码的质量和执行效率.

个人觉得第3点最致命,越复杂的功能往往执行效率越低下。而一些简单的字符串分析我们可以自已处理。

参考:

http://blog.csdn.net/beingstudio/articles/1806661.aspx

http://hi.baidu.com/lbird/blog/item/07e09c8282dbe992f703a6b0.html

http://hi.baidu.com/yinjianren/blog/item/28dce5ca75e30585c9176896.html


TAG: sscanf

 

评分:0

我来说两句

Open Toolbar