user-0 提问: 从字符串中提取信息的问题

回复:
user: user-1
content: 比如：//有字符串 //1_22_333,,4444__55555,_666666 //需要解析为 //1 //22 //333 //_ //4444 //55555 //666666 #include <stdio.h> char s[]="1_22_333,,4444__55555,_666666"; char c,*p,*p1; int st; void main() {     st=0;     p=s;     while (1) {         c=*p;         if (0==c) {             switch (st) {             case 1:printf("_\n");    break;             case 2:printf("%s\n",p1);break;             }             break;//         }         switch (st) {         case 0:                  if ('_'==c) {                            st=0;}             else if (','==c) {                            st=1;}             else             {p1=p;                       st=2;}         break;         case 1:                  if ('_'==c) {                            st=1;}             else if (','==c) {printf("_\n");              st=1;}             else             {p1=p;                       st=2;}         break;         case 2:                  if ('_'==c) {*p=0;printf("%s\n",p1);*p=c;st=0;}             else if (','==c) {*p=0;printf("%s\n",p1);*p=c;st=1;}             else             {                            st=2;}         break;         }         p++;     } } //1 //22 //333 //_ //4444 //55555 //666666

user: user-1
content: 引用 20 楼 fefe82 的回复:[quote=引用 18 楼 zhao4zhong1 的回复:] 有限状态自动机中可以使用if，可以使用for，可以调用外部函数。  看来我们对有限状态机的理解不太一样。 我说的是数学上的有限状态机，它只包括一个有限的输入符号集，一个有限的状态集，一个起始状态，一个状态转移函数，和一个接受状态集。  它的状态转移函数只能根据输入符号转移到另一个装态。没有循环、没有栈，没有存储。  如果状态转移的时候可以操作一个栈，那个它就变成了下推自动机，对应上下文无关文法。  如果在状态转移的时候还可以做更多的操作，那通常要用一个叫做图灵机的数学模型来描述。图灵机的能力是与现在的计算机的处理能力等价的（忽略量子计算机）。[/quote] 完全同意阁下的观点。 我的意思本来就是很多字符串过滤提取问题用正则表达式很难或根本无法实现，但用《编译原理》中的词法分析和有限状态自动机的思想写一段小程序，就能相对容易地实现。

user: user-2
content: 引用 18 楼 zhao4zhong1 的回复:有限状态自动机中可以使用if，可以使用for，可以调用外部函数。  看来我们对有限状态机的理解不太一样。 我说的是数学上的有限状态机，它只包括一个有限的输入符号集，一个有限的状态集，一个起始状态，一个状态转移函数，和一个接受状态集。  它的状态转移函数只能根据输入符号转移到另一个装态。没有循环、没有栈，没有存储。  如果状态转移的时候可以操作一个栈，那个它就变成了下推自动机，对应上下文无关文法。  如果在状态转移的时候还可以做更多的操作，那通常要用一个叫做图灵机的数学模型来描述。图灵机的能力是与现在的计算机的处理能力等价的（忽略量子计算机）。

user: user-1
content: 可以使用数组。

user: user-1
content: 有限状态自动机中可以使用if，可以使用for，可以调用外部函数。

user: user-2
content: 引用 15 楼 zhao4zhong1 的回复:来个最简单的练练手，请用正则表达式提取出以类似下列格式表示的一组正整数中的最大值： 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999,10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001  正则表达式，有限状态自动机，上下文无关文法，下推自动机，他们所能完成的工作很简单，就是判断某一个串是否属于某一种语言。 正则表达式，有限状态自动机 描述的正则语言；上下文无关文法，下推自动机 描述的上下文无关语言。  另外想请问一下，您觉得您用有限状态自动机应该怎么解决这个问题呢？

user: user-1
content: 引用 14 楼 fefe82 的回复:[quote=引用 11 楼 zhao4zhong1 的回复:] 那你可以试试参照CSV格式的RFC文档，写一个正则表达式用来提取任意符合CSV标准的数据文件中的指定字段的值。  看了一下，RFC4180 是吧，这个正则表达式貌似真的可以描述。  至于取值，使用各种正则扩展出来的取子串的操作应该也是可以做的。[/quote] 2.  Definition of the CSV Format     While there are various specifications and implementations for the    CSV format (for ex. [4], [5], [6] and [7]), there is no formal    specification in existence, which allows for a wide variety of    interpretations of CSV files.  This section documents the format that    seems to be followed by most implementations:     1.  Each record is located on a separate line, delimited by a line        break (CRLF).  For example:         aaa,bbb,ccc CRLF        zzz,yyy,xxx CRLF     2.  The last record in the file may or may not have an ending line        break.  For example:         aaa,bbb,ccc CRLF        zzz,yyy,xxx     3.  There maybe an optional header line appearing as the first line        of the file with the same format as normal record lines.  This        header will contain names corresponding to the fields in the file        and should contain the same number of fields as the records in        the rest of the file (the presence or absence of the header line        should be indicated via the optional "header" parameter of this        MIME type).  For example:         field_name,field_name,field_name CRLF        aaa,bbb,ccc CRLF        zzz,yyy,xxx CRLF  4.  Within the header and each record, there may be one or more     fields, separated by commas.  Each line should contain the same     number of fields throughout the file.  Spaces are considered part     of a field and should not be ignored.  The last field in the     record must not be followed by a comma.  For example:      aaa,bbb,ccc  5.  Each field may or may not be enclosed in double quotes (however     some programs, such as Microsoft Excel, do not use double quotes     at all).  If fields are not enclosed with double quotes, then     double quotes may not appear inside the fields.  For example:      "aaa","bbb","ccc" CRLF     zzz,yyy,xxx  6.  Fields containing line breaks (CRLF), double quotes, and commas     should be enclosed in double-quotes.  For example:      "aaa","b CRLF     bb","ccc" CRLF     zzz,yyy,xxx  7.  If double-quotes are used to enclose fields, then a double-quote     appearing inside a field must be escaped by preceding it with     another double quote.  For example:      "aaa","b""bb","ccc"  The ABNF grammar [2] appears as follows:  file = [header CRLF] record *(CRLF record) [CRLF]  header = name *(COMMA name)  record = field *(COMMA field)  name = field  field = (escaped / non-escaped)  escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE  non-escaped = *TEXTDATA  COMMA = %x2C  CR = %x0D  DQUOTE =  %x22  LF = %x0A  CRLF = CR LF   TEXTDATA =  %x20-21 / %x23-2B / %x2D-7E

user: user-1
content: 来个最简单的练练手，请用正则表达式提取出以类似下列格式表示的一组正整数中的最大值： 10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000,9999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999999,10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001

user: user-2
content: 引用 11 楼 zhao4zhong1 的回复:那你可以试试参照CSV格式的RFC文档，写一个正则表达式用来提取任意符合CSV标准的数据文件中的指定字段的值。  看了一下，RFC4180 是吧，这个正则表达式貌似真的可以描述。  至于取值，使用各种正则扩展出来的取子串的操作应该也是可以做的。

user: user-2
content: 引用 12 楼 zhao4zhong1 的回复:你还可以试试用正则表达式写一个C语言编译器。  C 语言已经远远超过个有限状态机的表示范围。它的基本语法需要使用上下文无关文法来表示。上下文无关文法需要使用下推自动机(pushdown automata)，有限状态自动机已经无能为力了。

user: user-1
content: 你还可以试试用正则表达式写一个C语言编译器。

user: user-1
content: 那你可以试试参照CSV格式的RFC文档，写一个正则表达式用来提取任意符合CSV标准的数据文件中的指定字段的值。

user: user-2
content: 引用 9 楼 zhao4zhong1 的回复:谁告诉你“正则表达式和有限状态机是等价的”，把他宰了！  From Wikipedia: https://en.wikipedia.org/wiki/Regular_language  Equivalent formalisms  A regular language satisfies the following equivalent properties:      it is the language of a regular expression (by the above definition)     it is the language accepted by a nondeterministic finite automaton (NFA)[note 1][note 2]     it is the language accepted by a deterministic finite automaton (DFA)[note 3][note 4]     it can be generated by a regular grammar[note 5][note 6]     it is the language accepted by an alternating finite automaton     it can be generated by a prefix grammar     it can be accepted by a read-only Turing machine     it can be defined in monadic second-order logic (Büchi-Elgot-Trakhtenbrot theorem[5])     it is recognized by some finite monoid, meaning it is the preimage of a subset of a finite monoid under a homomorphism from the free monoid on its alphabet[note 7]  Some authors use one of the above properties different from "1." as alternative definition of regular languages.  Notes 1. ⇒ 2. by Thompson's construction algorithm 2. ⇒ 1. by Kleene's algorithm 2. ⇒ 3. by the powerset construction 3. ⇒ 2. since the former definition is stronger than the latter 2. ⇒ 4. see Hopcroft, Ullman (1979), Theorem 9.2, p.219 4. ⇒ 2. see Hopcroft, Ullman (1979), Theorem 9.1, p.218 3. ⇔ 9. by the Myhill–Nerode theorem  当年学自动机的时候前4个的等价性是证过的。

user: user-1
content: 谁告诉你“正则表达式和有限状态机是等价的”，把他宰了！

user: user-2
content: 引用 7 楼 zhao4zhong1 的回复:[quote=引用 6 楼 genghaomail 的回复:] 终极解决方案，boost库的正则表达式 提醒：正则表达式不是万能的；而有限状态自动机是万能的。[/quote]  正则表达式和有限状态机不是等价的嘛 ... 所有可以用有限状态机的表达的语言，都可以找到一个等价的正则表达式。反之亦然。  正则表达式好多是用有限状态机实现的吧。

user: user-1
content: 引用 6 楼 genghaomail 的回复:终极解决方案，boost库的正则表达式 提醒：正则表达式不是万能的；而有限状态自动机是万能的。

user: user-3
content: 终极解决方案，boost库的正则表达式

user: user-1
content: sscanf(message, "name: %19[^,],age%d", name, &age);

user: user-4
content: 1.2真心快  楼主去了解下sscanf吧 顺便再了解下sprintf

user: user-5
content: 我想说12楼好快。。。