Learning notes for mastering Reg

2017-08-10  本文已影响0人  mxl0814

构建扫描器程序的两个重要方法

boolean hitEnd()


boolean requireEnd()
只有匹配成功该方法的返回值才有意义

消除循环

(normal)*(special(normal)*)*


special要能写成start(middle)*end

  1. start-endmiddle 匹配的是无交集的两部分
  2. startend是固化的文本,且startend至少存在一部分,middle可不存在


表达式的优化



\G使用之前匹配结束的位置

匹配44开头的5位数美国邮政编码(ZIP Codes)


3个办法


总结


匹配失败时候仍然会出现数据的不协调性


优缺点

推荐解决方法

正确表达式正确匹配一个字符串

关于正则引擎

  1. 捕获型括号
  2. 反向引用(是因为不支持1)
  3. 忽略优先量词(因为DFA尽量保证匹配当前位置最长的文本,所以没有意义)
  4. 所以也不会支持占有优先量词,和固化分组,和3的道理一样
  5. 不支持环视

传统型NFA的多选分支

一些匹配上的细节

肯定环视模拟固化分组

当环视成功以后,其中的备用状态将会被丢弃,所以可以使用回溯引用来捕获刚刚环视的内容如(?=(regex))\1,这个时候\1就是一段固定的文本值了,在对文本值\1进行匹配的过程中显然不会保存任何备用状态。所以使用\1的匹配达到了一个固化分组的匹配效果

关于regex测试器

关于NFADFA

简单的判断正则引擎

使用模式:
X(.+)+X
匹配文本:
XX-----------------------------------------------------------------------

如果匹配要花费很长的时间,那就是

之前匹配的结束位置,还是当前匹配的开始位置

在对一个文本进行多次匹配时,如果之前匹配的文本长度大于0,则下次匹配的时候将使用之前匹配的结束位置,否则传动装置将强行前进到下一个字符,就使用当前匹配的开始位置

匹配模式(?mode)和作用域

模式
作用域

(page: 135)

Java regex 字符组集合操作

假如要匹配除元音字母的其他任意英语小写字母,则可写为
[[a-z]&&[^aeiou]]
[...]&&[^....]来表示-的集合操作

同时也可以使用环视来模拟此功能:

上面的意思是先匹配一个字母,然后再确保匹配好的字符不能是元音字母


上面的意思是先把光标定位到除元音字母以外的任意字符的左边,然后匹配小写字母

Java使用regex的/x模式,内嵌注释

String regex = "(?x)M" +
                "#This is an Note\n" +
                "A#666\n";

Java字符串文本与正则表达式的关系

regex = "(?x)S S\t\\t\n\\n"

status value
Java src text (?x)S S\t\\t\n\\n
Java compiled text (?x)S STab\tLn\n
regex (?x)SS\t\n

因为(/x)的模式的影响,忽略所有的空白字符作为最后的regex,这可能会让人有点疑惑,那为什么\t\n依然存在,这是因为\t\n分别是两个字符\, t\, n字符的组合,这些字符本身都不是空白字符,只是regex用来匹配的时候会将\t\n视为元序列字符,分别匹配制表符和换行符

环视

metacharacter lookaround
</ (?<=\W)(?=\w)
/> (?<!\W)(?!\w)
\b </|/>, (?<=\W)(?=\w)|(?<=\w)(?=\W)
\B (?<=\W)(?=\W)|(?<=\w)(?=\w)

但元字符却具有更高的效率

451545类似的数值从右往左每3个数字添加一个逗号,且最右边不添加

Intellij IDEAregex的特点

[ \t]*( *|\t*)的区别

非捕获型括号(?:...)

如表达式([+-]?\d+(\.\d*)?)\s*([CF])([+-]?\d+(?:\.\d*)?)\s*([CF])

RegEx ([+-]?\d+(\.\d*)?)\s*([CF]) ([+-]?\d+(?:\.\d*)?)\s*([CF])
\1 ([+-]?\d+(\.\d*)?) ([+-]?\d+(?:\.\d*)?)
\2 (\.\d*) ([CF])
\3 ([CF]) NULL

书中可能的错误列表

疑问列表

  1. 表达式(a)?b\1还能匹配除文本aba以外的其他文本吗?(待研究)

API

子表达式定义

子表达式是只正则表达式中的一部分,通常是括号内的表达式
^(Subject|Date):中,(Subject|Date)通常被视为一个子表达式
其中SubjectDate也算是子表达式。而且,严格来讲
S u b j …… 这些都算是子表达式。

匹配位置的元字符\B\b\<\>

  1. 它们都匹配一个位置
  2. 它们都是元字符序列

使用regex检索文本的精确度

取决于我们对需要检索的文本的了解程度。
举个极端的例子,要匹配一个文件内的所有数字,显然可以使用
\d,但是如果我们清楚的明白我们的文件内的内容都是纯数字的话,
可以简单的使用.

关于grep

grep会在检查regex之前把换行符删除掉,
然后再用regex与每行删除完换行符剩下的内容进行匹配

关于在字符组中的元字符^

[^……]将会匹配未被列出的任意字符,
而且只有当^出现在[的最左边时,它才是一个元字符
[^^]第二个^就只是普通字符,这个模式的含义是它将匹配出除^字符以外的任意字符

关于元字符^$

更具体的说明

但如果使用了增强的行锚点模式

关于在字符组中的连字符-

上一篇下一篇

猜你喜欢

热点阅读