在第10章的学习和lab3的实验任务中,有用到正则表达式的地方。遂总结一下。
在本学期形式语言与自动机的学习中,已经了解了终结符,非终结符,产生式,范式,正则表达式的相关概念。针对软件构造,主要是记一些具体使用方法。
producer形式如下:
x ::= y z //concatenation: x matches y followed by z
x ::= y* //repeatition: x matches zero or more y
x ::= y | z //union: x matches y or z
匹配单个字符:
英文字符 . :匹配任意单个字符
例如表达式x.y可以匹配xoy,x;y,x[y,x&y等,.的位置可以匹配任意单个字符
英文中括号[ ]:匹配中括号内指定的字符集合中的单个字符
例如表达式x[wyd]y可以匹配xwy,wyy,wdy(注意只能匹配单个字符)
x[a-c]y可以匹配xay,xby,xcy,其中 - 代表范围,a-z及范围a至z的闭区间内的全部字母,0-9及0至9的数字字符
英文竖线符号 | :表示或
例如表达式x(w|y|dd)y可以匹配xwy,xyy,xddy,注意与x(wydd)y的区别,用 | 的情况,dd将被看成一个整体,故可以匹配xddy
前缀表达式 ^ :表示否,后面代表不想匹配的字符
例如表达式[^a],匹配除了字符a的单个字符;表达式[^a-c]表示除了范围a至c的字符(及字符abc)外的单个字符,该字符不一定是字母字符,特殊符号数字等均可,^可以近似看为取补(个人理解)
一些常用的表示次数的后缀表达式如下,后缀表达式拥有最高的优先级 ,括号可以替代优先级
y* | 匹配>=0个y |
y+ | 匹配>0个y |
y? | 匹配0或1个y |
y{n} | 匹配恰好n个y |
y{n,} | 匹配至少n个y |
y{,n} | 匹配至多n个y |
y{n,m} | 匹配[n,m]个y(闭区间) |
注意下列表达式:
最初我对此也很困惑,以为是组合使用之意。例如x?+,我认为是匹配至少1次x?,那就是匹配至少1次的0/1个x,即任意个数的x,但程序运行结果告诉我并不是这样,而是0/1次x,即像上述图示一样,运行下列代码进行测试:
String s1 = "";
String s2 = "y";
String s3 = "yy";
System.out.println(s1 + ":" + s1.matches("y{2,}?"));
System.out.println(s2 + ":" + s2.matches("y{2,}?"));
System.out.println(s3 + ":" + s3.matches("y{2,}?"));
结果如下,并非任意个y,只能匹配0/1个y
:false
y:false
yy:true
后来查阅资料得知,第一列对应贪婪匹配,第二列reluctant对应懒惰匹配,第三列对应占有匹配
懒惰匹配:? 匹配最短的符合正则表达式的
贪婪匹配:+匹配最长的符合正则表达式的
参考文章:https://www.jb51.net/tools/zhengze.html
注意在正则表示中,如果想符号不被解析成特殊含义,需要在符号前加 \ :
例如x[a-c]y匹配xay,xby,xcy;而x[a\-c]y匹配xay,x-y,xcy
一些快捷符号及其含义:
\d | 等价于[0-9] |
\D | 等价于[^0-9] |
\w | 等价于[0-9A-Z_a-z] 其中_是下划线,即\w的匹配范围为: 数字0至9,字母a-z大小写均可,下划线_ |
\W | 等价于[^0-9A-Z_a-z] |
\s | 空字符,等价于[\t\n\r\f] |
\S | 非空字符,等价于[^\t\n\r\f] |
\r | 空字符,例如\n换行符,\tab制表符等 |
一些元字符及其含义:
^ | 行的开始 |
$ | 行的结束 |
\b | 一个单词的间隔 |
\B | 一个non-word的间隔 |
\A | 输入的开始 |
\z | 输入的结束 |
\Z | 输入的结束,如果有终结符的话不包括终结符 |
\G | 上一次匹配的结束 |
以上仅是个人软构学习心得总结,如有不当,欢迎指正!