美文网首页
flex正则表达式常用语法浅析(1)

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

作者: Minority | 来源:发表于2020-02-23 15:51 被阅读0次

一、基本用法:

'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

相关文章

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

    一、基本用法: 注意: 当^在[ ]内时表示 "非" ,当直接出现在匹配式内表示匹配一行的开头。 二、示例 1. ...

  • Flex语法浅析

    不了解Flex的同学,可以先温习一下上一节的内容Flex和Bison背景介绍[https://www.jiansh...

  • 【正则表达式】 基本语法及常用查询

    一.正则表达式 **1.基本语法 ** 2.常用:

  • 正则表达式的使用

    1.正则表达式的语法 iOS开发中正则表达式的基础使用 2.正则表达式不常用的语法 Q:经常看见的正则前面的 (?...

  • re模块入门

    正则表达式常用操作符 正则表达式语法实例 经典正则表达式实例

  • iOS中正则表达式使用及关键语法

    iOS中高效使用正则表达式 代码示例展示 常用的表达式 正则表达式的关键语法 表1.常用的元字符 字符转义如果你想...

  • Flex 布局教程

    一、Flex 布局教程:语法篇 Flex 布局教程:语法篇 二、Flex 布局教程:实例篇 Flex...

  • Python3.6:re模块详解

    常用的正则表达式符号 包含'\'的正则表达式特殊序列 常用的语法 #*,+,?都是贪婪匹配,也就是尽可能的匹配 后...

  • ReactNative flex布局&es6

    一、ES6常用语法 & 新特性二、Flex布局 & 样式三、一般组件的使用 ES6常用语法 & 新特性 ECMAS...

  • 正则表达式的使用 - swift3.1

    正则表达式的使用文件如下: 使用方法: 补充一些正则表达式中常用的语法,方便扩展更多判断 1 . 校验密码强度 密...

网友评论

      本文标题:flex正则表达式常用语法浅析(1)

      本文链接:https://www.haomeiwen.com/subject/lpsjqhtx.html