📄 re_history.txt
字号:
re_history.txt
正则表达式解析库历史和说明
于2004年在北京写于创意鹰翔公司
版权申明:
作者放弃除著作署名权之外的任何权益。你可以在保留此申明的前提下,自由的,无限制的
分发、修改和使用本函数库。
如果你有任何建议和BUG汇报,欢迎你联系原始作者:tearshark@163.com
原始作者 : lanzhengpeng(兰征鹏)
Modify time : 2006-03-16 12:13
-------------------------------------------------------------------------------
历史:
version 125:
2007-03-02
修改了一些细节上的问题。
version 124:
2006-03-16
在假定替换后的字符串类型支持 String(CharT *,size_t)从一段指定长度
的字符串指针构造一个字符串 和 支持 operator +=(const String &)来
连接字符串的功能的前提下,将replace功能实现了。
version 123:
2005-12-11
工作变迁,邮箱地址更改了。同时修改了一些说明文字的错误————输入法
太聪明了也不好。
version 121:
2005-03-12
完成R!语法,表示R匹配的时候,R!不匹配。如果R!匹配,则跳过一个字符。
之所以不做成!R的语法(更适合经验中的用法),是因为这样一来,
会设计到与其他操作符的优先级问题,语法分析上比较困难,而且一些歧义
无法处理:如!R|R,使算作(!R)|R还是!(R|R);又如:!R*,是(!R)*还是!(R*)。
现在的做法就比较容易处理:R!|R=>(R!)|R,R!*=>(R!)*,R*!=>(R*)!
当初还考虑过R!语法一直匹配到失败为止,后来考虑到可以使用*,+,?等再
修饰R!语法来替代,故只匹配一次。
插曲:此语法在2004年末已经写过一次,后来大概因为在三家公司跑来跑去
以及自己两台电脑上的同步错误,导致新写的代码被覆盖了。
version 120:
2004-10-03
修改多行匹配,'^'作为行开始时无匹配不中断匹配过程
version 109:
2004-07-16
增加R<m:>语法,表示R至少重复m次,至多可无限重复
version 108:
2004-06-22
为迎合VC7.1,到处加typename。无聊透顶,MS怎么请了Borland的
开发人员来做VS.Net?!
version 107:
2004-06-15
修改"ToHex"为"to_hex",因为"ToHex"跟其他函数库里的一个宏冲突
同时也修改"ToOct","ToInt"分别为"to_oct","to_int"
修改多次使用相同的re_result累计结果的BUG
简化"\s"的定义
列举常见表达式
增加"\f"作为浮点数(非科学计数法)
version 106:
2004-06-15
由于现有的分析方案分析"|"和"&"比较困难,遂增加首先分块,然后针对块
进行分析
修改匹配函数接口和相关代码,使得match函数线程安全
version 105:
2004-06-14
增加"\s"作为预定义的C字符串
增加"\o"作为预定义的C注释
修正类似"*","*?"重复表达式前没有表达式分析错误
修正部分递归分析中返回值错误问题
修正分析错误后仍然做优化的问题
完成"|"和"&"的分析和匹配
增加"\p"作为预定义的C++注释
把(),{}作为语法错误
version 104:
2004-06-07
在匹配的时候检测无穷循环
修改非贪婪重复匹配中的BUG
修改匹配行结尾的BUG
!R的实现实在太有问题。一个细节无法解决:当R匹配的时候,!R是不匹配的,
因此,不能移动匹配的位置。如果R不匹配,则不知道当前位置究竟在哪里。
或者从来就不移动匹配位置?那有什么意义?
决定取消!R语法,暂时保留相关代码
version 103:
2004-06-06
精确匹配完成
转义支持\x,\o以指定十六进制和八进制及十进制
彻底完成转义操作
完成*?,+?,??的分析和匹配
<m:n>?的分析和匹配
version 102:
2004-06-05 晚
完成*,+,?的分析和匹配
完成^,$的分析和匹配
.分析和匹配
2004-06-06 凌晨
()分析和匹配
{}分析和匹配
<m:n>分析和匹配
单字节码,多字节码,UNICODE的萃取器完成
version 101:
2004-06-02 框架代码完成
完成[],[^]的分析和匹配
version 100:
2004-06-02 开始此正则表达式的编写
-------------------------------------------------------------------------------
特注:
由于无全局函数或变量,所以,不同的re_pattern变量之间是线程安全
match()函数线程安全
-------------------------------------------------------------------------------
支持的正则表达式规则:
R = NULL 空表达式也为正则表达式
R = R 正则表达式也是正则表达式
R = A 单个字符
R = . 任意字符
R = ^ 起始
R = $ 结尾(单行)和行结尾(多行)
R = [] 范围之内 除^,],\之外的字符不需要转意
R = [^] 范围之外 除^,],\之外的字符不需要转意
R = (R) 分块
R = {R} 成组。按照顺序编号
R = R* 尽可能多的重复零次以上(贪婪算法)
R = R+ 尽可能多的重复一次以上(贪婪算法)
R = R? 尽可能多的匹配零或一次(贪婪算法)
R = R*? 尽可能少的重复零次以上(非贪婪算法)
R = R+? 尽可能少的重复一次以上(非贪婪算法)
R = R?? 尽可能少的匹配零或一次(非贪婪算法)
R = R<m:n> 尽可能多的重复最少m次,最多n次,m可省略(贪婪算法)
R = R<:n> R<m:n> m=0的简写
R = R<m:> R<m:n> n=无穷大的简写
R = R<m:n>? 尽可能少的重复最少m次,最多n次,m可省略(非贪婪算法)
R = R|R 匹配两个中任意一个
R = R&R 同时匹配两个
R = R! 如果R匹配,则当前不匹配
R = \A 转意
\r "\r" // Return
\t "\t" // Tab
\n "\r?\n" // Newline
\a "[a-zA-Z0-9]" // alpha numeric
\b "[ \\t]" // white space (blank)
\c "[a-zA-Z]" // alpha
\d "[0-9]" // digit
\f "[+\-]?([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+)[fF]?"// Float
\h "[0-9a-fA-F]" // hex digit
\o "/\\*.*?\\*/", // c cOmment
\p "//.*?\\n|$", // cPp comment
\q "(\"[^\"]*\")|(\'[^\']*\')" // quoted string
\s "\"([^\\\\\"]*(\\\\.)*[^\\\\\"]*)*?\"", // c string
\w "[a-zA-Z]+" // simple word
\z "[0-9]+" // integer
-------------------------------------------------------------------------------
问题:
^$ 匹配空串?
$^ 单行下用无匹配还是空串?多行下匹配上一行和下一行?
AB^ 永无匹配
$AB 单行下永无匹配,多行下匹配上一行和下一行的AB
() 匹配空串?根本无意义
{} 根本无意义
((R)) 是否优化重复
{R}*
{R}+
{R}?
{R}*?
{R}+?
{R}?? 成组重复(包括间接重复)
可是在实际应用中,希望成组的顺序号是固定的。
如此以来,很难知道那个组匹配的那些字符,从而失去使用意义
但是,要检查这样的情况,似乎得不偿失
R<m:n>
R<m:n>? m>n?
R<0:0>
R<0:0>? 无意义
必须的
R<-1:-1>
R<-1:-1>? 错误
R<:n>
R<:n>? 重复0到n次
R<m:>
R<m:>? 重复m到无穷次
R<:>
R<:>? 等同于R*
[m-n]
[^m-n] m>n? 应该允许吧,谁知道汉字编码呢?
\123456 当我只需要'\123','4','5','6'时怎么办?通过改变顺序或添加()可解决否?
-------------------------------------------------------------------------------
结论:
^ 只匹配起始地址。如果匹配行结尾的下一个字符,涉及到字符回滚,
对于多字节,这是个比较麻烦的事;而且,这就变相的成为$^语法了
随之而来的问题是$^和AB^没有意义,但作为可接受的语法
() 不允许
{} 不允许
((R)) 不做优化
{R}*
{R}+
{R}?
{R}*?
{R}+?
{R}?? 成组重复(包括间接重复)由于很难检查间接重复,就作为可接受的语法。
在每个组中,标记顺序号来标示是哪个组
(R)
{R} 将阻隔表达式的连续性。如R*?R是连续的,作为一个表达式解析
但是{R*?}R是被分成了两个表达式解析,其匹配结果必然不同于R*?R
-------------------------------------------------------------------------------
常见表达式:
IP:
([0-2]??[0-9]<1:2>\.)<3:3>[0-2]??[0-9]<1:2>
C/C++中空白字符:
[ \t\r\n]
C注释:
/\*.*?\*/
已定义为
\o
C++式注释:
//.*?\n|$
已定义为
\p
C++注释:
(/\*.*?\*/)|(//.*?\n|$)
或:
\o|\p
C字符串:
"([^\\"]*(\\.)*)*?"
或
\s
UINCODE字符串:
L"([^\\"]*(\\.)*)*?"
或
L\s
C/C++变量名
[_a-zA-Z][_0-9a-zA-Z]*
C/C++中十六进制表示法:
0[xX][0-9a-fA-F]+
或
0[xX]\h+
汇编中十六进制表示法:
[0-9a-fA-F]+[hH]
或
\h+[hH]
八进制表示法:
0[oO][0-7]+
二进制表示法:
[01]+[bB]
十进制数字:
[0-9]+[lL]?
整数:
[+\-]?[0-9]+[lL]?
浮点数:
[+\-]?([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+)[fF]?
或
\f
科学计数法:
[+\-]?([0-9]+\.[0-9]*)|([0-9]*\.[0-9]+)[eE][+\-]?[0-9]+
E-mail:
[_a-zA-Z][_0-9a-zA-Z]*@[^.]+\..+
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -