不包括文字引号的字符串的正则表达式
Regular expression for string excluding literal quotation marks
我正在尝试解析以下配置文件。
[ main ]
e_type=0x1B
username="username"
appname="applicationname"
在下面指定的 lex 文件 (test.l
) 中,STR 的正则表达式是 \"[^\"]*\"
以便它识别 quotes.When 中的所有内容 我访问 [=14= 的值] 在解析器文件中使用 $N 变量,它包含文字 string.I 只是想要
username
和 applicationname
即没有字符串引号。
有没有标准的方法来实现这个。
我有以下 lex 文件 (test.l
)
%option noyywrap
%option yylineno
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "y.tab.h"
int yylinenu = 1;
int yycolno=1;
/**
* Forward declerations
**/
void Number ();
void HexaNumber ();
unsigned char getHexaLex (char c);
unsigned int strtol16 (char * str);
%}
%option nounput
%option noinput
%option case-insensitive
/*-----------------------------------------------------------------
Some macros (standard regular expressions)
------------------------------------------------------------------*/
DIGIT [0-9]
HEXALETTER [a-fA-F]
HEXANUMBER [0][x](({DIGIT}|{HEXALETTER})+)
NUM {DIGIT}+
HEXA ({DIGIT}|{HEXALETTER}|[*])
STR \"[^\"]*\"
WSPACE [ \t]*
NEWLINE [\n\r]
/*----------------------------------------------------------------
The lexer rules
------------------------------------------------------------------*/
%%
e_type { yylval.str = yytext; return T_E_TYPE; }
main { yylval.str = yytext; return T_MAIN_SECTION;}
{HEXANUMBER} { yylval.n = atoi(yytext); HexaNumber(); return T_NUMBER; }
= { return T_EQUAL; }
"[" { return T_OPEN_BRACKET; }
"]" { return T_CLOSE_BRACKET;}
appname { Custom_tag(); return T_APPNAME; }
username { Custom_tag(); return T_APPNAME; }
[^\t\n\r] { }
{WSPACE} { } /* whitespace: (do nothing) */
{NEWLINE} {
yylinenu++;
return T_EOL;
}
{STR} { Generic_string(); return T_STRING;}
%%
void Number () {
yylval.n = atol(yytext);
}
void Generic_string() {
yylval.str = malloc(strlen(yytext)+1);
strcpy (yylval.str, yytext);
}
您有一个指向匹配标记 (yytext
) 及其长度 (yyleng
) 的指针,因此删除引号非常简单:
void Generic_string() {
yylval.str = malloc(yyleng - 1); // length - 2 (quotes) + 1 (NUL)
memcpy (yylval.str, yytext + 1, yyleng - 2); // copy all but quotes
yylval.str[yyleng - 2] = 0; // NUL-terminate
}
就我个人而言,我建议避免在 Generic_string
中使用全局变量,既可以简化可重入扫描器的未来实现,也可以使过程更加灵活:
{STR} { yylval.str = duplicate_segment(yytext + 1, yyleng - 2);
return T_STRING;
}
/* ... */
char* duplicate_segment(const char* token, int token_length) {
char* dup = malloc(token_length + 1);
if (!dup) { /* handle memory allocation error */ }
memcpy(dup, token, token_length);
dup[token_length] = 0;
return dup;
}
我正在尝试解析以下配置文件。
[ main ]
e_type=0x1B
username="username"
appname="applicationname"
在下面指定的 lex 文件 (test.l
) 中,STR 的正则表达式是 \"[^\"]*\"
以便它识别 quotes.When 中的所有内容 我访问 [=14= 的值] 在解析器文件中使用 $N 变量,它包含文字 string.I 只是想要
username
和 applicationname
即没有字符串引号。
有没有标准的方法来实现这个。
我有以下 lex 文件 (test.l
)
%option noyywrap
%option yylineno
%{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "y.tab.h"
int yylinenu = 1;
int yycolno=1;
/**
* Forward declerations
**/
void Number ();
void HexaNumber ();
unsigned char getHexaLex (char c);
unsigned int strtol16 (char * str);
%}
%option nounput
%option noinput
%option case-insensitive
/*-----------------------------------------------------------------
Some macros (standard regular expressions)
------------------------------------------------------------------*/
DIGIT [0-9]
HEXALETTER [a-fA-F]
HEXANUMBER [0][x](({DIGIT}|{HEXALETTER})+)
NUM {DIGIT}+
HEXA ({DIGIT}|{HEXALETTER}|[*])
STR \"[^\"]*\"
WSPACE [ \t]*
NEWLINE [\n\r]
/*----------------------------------------------------------------
The lexer rules
------------------------------------------------------------------*/
%%
e_type { yylval.str = yytext; return T_E_TYPE; }
main { yylval.str = yytext; return T_MAIN_SECTION;}
{HEXANUMBER} { yylval.n = atoi(yytext); HexaNumber(); return T_NUMBER; }
= { return T_EQUAL; }
"[" { return T_OPEN_BRACKET; }
"]" { return T_CLOSE_BRACKET;}
appname { Custom_tag(); return T_APPNAME; }
username { Custom_tag(); return T_APPNAME; }
[^\t\n\r] { }
{WSPACE} { } /* whitespace: (do nothing) */
{NEWLINE} {
yylinenu++;
return T_EOL;
}
{STR} { Generic_string(); return T_STRING;}
%%
void Number () {
yylval.n = atol(yytext);
}
void Generic_string() {
yylval.str = malloc(strlen(yytext)+1);
strcpy (yylval.str, yytext);
}
您有一个指向匹配标记 (yytext
) 及其长度 (yyleng
) 的指针,因此删除引号非常简单:
void Generic_string() {
yylval.str = malloc(yyleng - 1); // length - 2 (quotes) + 1 (NUL)
memcpy (yylval.str, yytext + 1, yyleng - 2); // copy all but quotes
yylval.str[yyleng - 2] = 0; // NUL-terminate
}
就我个人而言,我建议避免在 Generic_string
中使用全局变量,既可以简化可重入扫描器的未来实现,也可以使过程更加灵活:
{STR} { yylval.str = duplicate_segment(yytext + 1, yyleng - 2);
return T_STRING;
}
/* ... */
char* duplicate_segment(const char* token, int token_length) {
char* dup = malloc(token_length + 1);
if (!dup) { /* handle memory allocation error */ }
memcpy(dup, token, token_length);
dup[token_length] = 0;
return dup;
}