flex正则表达式常用语法浅析(1)

一、基本用法:

'x'          匹配字符 'x' 
'.’          除换行符外的任何字符(字节)
'[xyz]’      字符类别;在这种情况下,模式匹配‘x’、'y'、'z'
'[abj-oZ]’   具有范围的“字符类”;匹配“ a”,“ b”,“ j”到“ o”中的任何字母或“ Z”
'[^A-Z]’    “否定字符类”,即该类中的字符以外的任何字符。在这种情况下,任何字符都不能包含大写字母。
'[^A-Z\n]’   除大写字母或换行符外的任何字符
'[a-z]{-}[aeiou]’   小写辅音
'r*’          零个或多个r,其中r是任何正则表达式
'r+’          一个或多个 r
'r?’         零或一个r(即“可选r”)
'r{2,5}’      从两到五​​个
'r{2,}’      两个或多个
'r{4}’        恰好4个
'{name}'      扩展“name”定义,把别处定义的name拿过来用
'"[xyz]\"foo"' 文字字符串:   [xyz]” foo,外面的""表示是一个字符串,里面的\"表示是一个转义字符,匹配' " '。 
'\X'           如果X是'a','b','f','n','r','t'或'v',则ANSI-C解释为'\x'。即普通字符不转义,就是表示'\x'。
               否则,为文字“X”(用于转义诸如“ *”之类的运算符)
'\0'          一个NUL字符(ASCII代码0)
'\123’        八进制值123的字符
'\x2a’        十六进制值为2a的字符
'(r)'        匹配“ r”;括号用于改变优先级(请参见下文)

'rs'                正则表达式“ r”后跟正则表达式“ s”;称为串联
'r|s'                “ r”或“ s”
'r/s’              一个“ r”,但前提是其后跟一个“ s”。确定此规则是否为最长匹配项时,
                    将包含用“ s”匹配的文本,但在执行操作之前,该文本将返回到输入。因此,
                   该操作只会看到与“ r”匹配的文本。这种模式称为尾随上下文。 (flex不能正确
                   匹配某些“ r / s”组合。有关危险的尾随上下文,请参见限制。)
'^r’              一个“ r”,但仅在一行的开头(即刚开始扫描时,或在扫描换行符之后)。
'r$’              一个“ r”,但只能在一行的末尾(即,在换行符之前)。等同于“ r/\n”。
                   请注意,flex的“换行符”概念与C编译器用来将flex解释为“ \n”的情况完全相同。
                   特别是,在某些DOS系统上,您必须自己过滤掉输入中的“ \r”,
                   或显式地将“ r /\r\ n”用作“ r $”。
'<s> r’             一个“ r”,但仅在起始条件s中(请参阅“起始条件”以了解起始条件)。
'<s1,s2,s3> r’  同上,但在任何启动条件s1,s2或s3中。
'<*> r’             任何开始条件下的“ r”,甚至是排他条件。
'<< EOF >>'         文件结束。
‘<s1,s2><<EOF>>’   在开始条件s1或s2中的文件结束

注意:^[ ]内时表示 "非" ,当直接出现在匹配式内表示匹配一行的开头。

二、示例

1. 示例1

code:

%%

"xyz"   printf("quoted xyz\n");
abc     printf("unquoted abc\n");
123     printf("digit 123");

%%

int main() {
        
        yylex();
        return 0;
}

int yywrap() {
        return 1;
}

运行过程:

结果分析:
可以看出,当输入为abce时,匹配规则abc匹配成功。其后面的字符e执行默认动作打印。如果这里没有任何规则,默认就是直接回显。并且每次匹配成功后的输出都会进行换行。

2. 示例2

code:

%%

abc     printf("unquoted abc\n");
abcd    printf("longer\n");
"xyz"   printf("quoted xyz\n");
xyz     printf("unquoted xyz\n");
#       return 0;

%%

int main() {
        
        yylex();
        return 0;
}

int yywrap() {
        return 1;
}

运行过程:
用flex编译时会出现以下错误:


原因是上面的匹配规则

"xyz" printf("quoted xyz\n");
xyz printf("unquoted xyz\n");

是相同的,即不加 " " 和加都是一个效果。把其中一个去掉之后再编译如下:



输入abcd,可以看到进行匹配的规则是abcd,而不是abc。即flex遵从最长匹配原则。

3. 示例3

code:

[abc]         printf("single character\n");
[A-GO-T]      printf("character ranges\n");
[a-z]{2,3}    printf("2~3 characters\n");
[0-9]+        printf("multiple digits\n");
[[:alnum:]]+     printf("multiple alphanumber\n");
#       return 0;

测试结果很有意思。如果没有规则(该规则是c中判断数字和字母的函数,可以匹配数字和字母)

[[:alnum:]]+     printf("multiple alphanumber\n");

则在测试“1a2b3”时会出现

1a2b3
multiple digits
single character
multiple digits
single character
multiple digits

加上这条规则的话,输出

abc
2~3 characters

1a2b3
multiple alphanumber

4. 示例4

code:

[^abc]         printf("except a b c\n");
^ab$           printf("start with a end with b\n"); //只能是ab
^a.b$          printf("with more characters\n");  //匹配a开头,b结尾,中间不是换行符的任意字符
[.]            printf("a dot\n");    // 通配符在[]中就表示一个点(dot)
(foo|bar)+     printf("multiple foo bar\n");  //字符串foo或者字符串bar重复多次
foo|bar+       printf("multiple r\n");   //字符串foo或者字符串bar
"a.b"          printf("a.b exactly\n");  //字符串"a.b"
(.|\n)?        printf("everything.\n");  //匹配所有

来测试一下效果:

x
except a b c
except a b c
b
everything.
except a b c
ab
start with a end with b
except a b c
axb
with more characters
except a b c

之所以输入x会输出两次except a b c,是因为对\n的处理不够好,导致回车换行符也被视作except a b c。对上述代码进行优化一下

%%

\n              printf("\n");

[^abc]         printf("except a b c\n");

^ab$           printf("start with a end with b\n");

^a.b$          printf("with more characters\n");

(foo|bar)+     printf("multiple foo bar\n");

foo|bar+       printf("multiple r\n");

"a.b"          printf("a.b exactly\n");

(.|\n)?        printf("everything.\n");
%%

int main(int argc, char* argv[]) {
    yylex();
    return 0;
}

int yywrap() {
    return 1;
}

再看一下结果:

aa.bb
everything.
a.b exactly
everything.

a.b
with more characters

a*b
with more characters

foo
multiple foo bar

foobar
multiple foo bar

barr
multiple r

5. 示例5

code:

%%

(.|\n)*        printf("everything.\n");

%%

int main(int argc, char* argv[]) {
    yylex();
    return 0;
}

int yywrap() {
    return 1;
}

上述匹配规则是"匹配所有字符"。测试的时候,如果是直接读入文件,直接显示一次执行动作的结果;如果是交互式输入,需要手动输入EOF(Linux下是新行开始的ctrl+D),而且只有在新行按下ctrl + D时,才会把之前所输入的所有字符进行回显。



本文参考:https://zhuanlan.zhihu.com/p/65490271
更详细的flex使用方法:https://zhuanlan.zhihu.com/p/108167693

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,458评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,030评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,879评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,278评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,296评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,019评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,633评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,541评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,068评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,181评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,318评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,991评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,670评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,183评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,302评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,655评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,327评论 2 358

推荐阅读更多精彩内容

  • 正则表达式练习题点击这里 创建一个正则表达式 使用一个正则表达式字面量,其由包含在斜杠之间的模式组成,如下所示: ...
    打铁大师阅读 1,257评论 0 6
  • 在C语言中,五种基本数据类型存储空间长度的排列顺序是: A)char B)char=int<=float C)ch...
    夏天再来阅读 3,348评论 0 2
  • \ :将下一字符标记为特殊字符、文本、反向引用或八进制转义符。例如,"n"匹配字符"n"。"\n"匹配换行符。序列...
    小沙鹰168阅读 544评论 0 1
  • 9.19--9.23 第7章 正则表达式 正则表达式是一个拆分字符串并查询相关信息的过程。 推荐练习网站: js ...
    如201608阅读 1,035评论 0 4
  • 正则表达式学习笔记 一篇记录了学习正则表达式的笔记。 1. 转义字符 在 HTMl 中转义字符以 & 符号开头,分...
    heyi_let阅读 394评论 0 0