长时间不用正则,语法都忘了; 以下是基于之前的资料又结合 msdn 复习整理的记录:
TRegex.Create('abc');
abcde ABCDE abcde
默认区分大小写
TRegex.Create('abc',[roIgnoreCase]);
abcde ABCDE abcde
使用 roIgnoreCase 选项,可不区分大小写
TRegex.Create('B');
ABC
匹配某个 Ansi 字符有多种方法,下面都是匹配 'B': TRegex.Create('\x42'); { 十六进制,只能 1-2 位 } TRegex.Create('\102'); { 八进制,须 3 位 } TRegex.Create(#66); { 只用于 Delphi } TRegex.Create(#$42); { 只用于 Delphi } { 当前版本不支持 \u 和 \U; 类似不支持的还有: \L \I \N \c }
TRegex.Create('万');
万一
匹配某个 UniCode 字符方法不多,下面也是匹配 '万': TRegex.Create(#19975); { 只用于 Delphi } TRegex.Create(#$4E07); { 只用于 Delphi } { 当前版本不支持 \u 和 \U }
TRegex.Create(' ');
A B C
这是匹配一个空格,还可以: TRegex.Create('\x20'); { 十六进制,只能 1-2 位 } TRegex.Create('\040'); { 八进制,须 3 位 } TRegex.Create(#32); { 只用于 Delphi } TRegex.Create(#$20); { 只用于 Delphi }
TRegex.Create('\*');
A*B
下列字符在正则表达式中有特殊意义,使用时需要转义: . $ ^ { [ ( | ) * + ? \
需要转义的还有一些空白字符:
\r { 回车符 } \n { 换行符 } \f { 换页符 } \t { 制表符 } \v { 垂直制表符 } \e { Esc 符 } \a { 响铃 } \b { 退格符; 只用在 [] 和替换模式中,更多时候表示单词边界 } 给不需要转义的字符前置 \ 后,会忽略 \
TRegex.Create('Monday|Wednesday|Friday');
Monday Tuesday Wednesday Thursday Friday Saturday Sunday
| 是或者
TRegex.Create('[BD]');
ABCDE
包含在 [] 中的...相当于 | (或者)
TRegex.Create('[^BD]');
ABCDE
不在 [] 中的...
TRegex.Create('[A-Z]');
RegularExpressions_1.0 适用于 Delphi 2009 及之后的版本
匹配大写字母
TRegex.Create('[a-z]');
RegularExpressions_1.0 适用于 Delphi 2009 及之后的版本
匹配小写字母
TRegex.Create('[0-9]');
RegularExpressions_1.0 适用于 Delphi 2009 及之后的版本
匹配阿拉伯数字
TRegex.Create('[A-Za-z]');
RegularExpressions_1.0 适用于 Delphi 2009 及之后的版本
匹配英文字母
TRegex.Create('[0-9.]');
RegularExpressions_1.0 适用于 Delphi 2009 及之后的版本
匹配阿拉伯数字和小数点; 小数点 . 不在 [] 中时可匹配任意字符
TRegex.Create('[A-C]X');
AX BX CX DX CS DS ES GS FS EAX EBX ECX EDX
TRegex.Create('['#$4E00'-'#$9FFF']');
万一的 Delphi 博客
这个表达式是匹配汉字,也可以这样写: TRegex.Create('[一-龥]'); 前面提到,当前版本暂不支持 \u,如果支持的话可以这样写: TRegex.Create('[\u4E00-\u9FFF]'); 其实像这种匹配应该使用字符集匹配,可惜暂不支持,后面会有提到.
TRegex.Create('Go{2}gle');
Ggle Gogle Google Gooogle Goooogle Gooooogle
{m} 表示重复 m 次
TRegex.Create('Go{2,4}gle');
Ggle Gogle Google Gooogle Goooogle Gooooogle
{m,n} 表示重复 m 到 n 次
TRegex.Create('Go{2,}gle');
Ggle Gogle Google Gooogle Goooogle Gooooogle
{m,} 表示重复 m 次以上
TRegex.Create('Go+gle');
Ggle Gogle Google Gooogle Goooogle Gooooogle
+ 表示 1 个或多个
TRegex.Create('Go*gle');
Ggle Gogle Google Gooogle Goooogle Gooooogle
* 表示 0 个或多个
TRegex.Create('Go?gle');
Ggle Gogle Google Gooogle Goooogle Gooooogle
? 表示 0 个或 1 个; 它还用于非贪婪匹配和子表达式
TRegex.Create('\d');
A1 B2 C3
\d 匹配阿拉伯数字; 相同于 [0..9]
TRegex.Create('\D');
A1 B2 C3
\D 匹配非数字字符,包括空字符; 相同于 [^0..9] 或者 [^\d]
TRegex.Create('\s');
A1 B2 C3
\s 匹配空白; 相同于 [\f\n\r\t\v]
TRegex.Create('\S');
A1 B2 C3
\S 匹配非空字符; 相同于 [^\f\n\r\t\v]
TRegex.Create('\w');
A_1 B-2 C=3
\w 匹配单词字符; 相同于 [A-Za-z_0-9]
TRegex.Create('\W');
A_1 B-2 C=3
\W 匹配非单词字符; 相同于 [^A-Za-z_0-9]
TRegex.Create('.');
AAA
BBB
CCC
. 匹配除换行符以外的任意字符; 如果指定了 roSingleline 选项,也能匹配换行符,像这样: TRegex.Create('.',[roSingleline]); 也有例外: 如果 . 在 [] 中,它只代表它自己.
TRegex.Create('\bDelphi\b');
Embarcadero_Delphi,DelphiBBS,MyDelphiBBS,www.Delphi.com
\b 表示单词边界; 另外 \b 在 [] 和替换模式中表示退格符
TRegex.Create('\bDelphi');
Embarcadero_Delphi,DelphiBBS,www.Delphi.com
\b 示例: 右边是边界
TRegex.Create('Delphi\b');
Embarcadero_Delphi,www.Delphi.com
\b 示例: 左边是边界
TRegex.Create('\BDelphi\B');
Embarcadero_Delphi,MyDelphiBBS,www.Delphi.com
\B 和 \b 相反,匹配非单词边界
TRegex.Create('\b\w+\b');
one two three four
这是匹配所有英文单词的例子
TRegex.Create('\p{P}');
Ok? Ok!-是吗?是的!
\p 组合 {} 可以匹配更多的 UniCode 字符,\p{P} 是匹配标点符号;
它还可以细化,譬如 \p{Pi} 匹配前引号 \p{Pf} 匹配后引号; 下面是详细列表:
C { 控制字符; 细分为: Cc(控制)、Cf(格式)、Cs(代理项)、Co(私用)、Cn(说是未使用,但相当于"其他") } L { 字母; 细分为: Lu(大写)、Ll(小写)、Lt(词首大写)、Lm(修饰符)、Lo(其他) } M { 附加符号; 细分为: Mn(非间距)、Mc(间距组合)、Me(封闭) } N { 数字; 细分为: Nd(十进制)、Nl(字母)、No(其他) } P { 标点; 细分为: Pc(连接符)、Pd(短划线)、Ps(开始)、Pe(结束)、Pi(前引号)、Pf(后引号)、Po(其他) } S { 符号; 细分为: Sm(数学)、Sc(货币)、Sk(修饰符)、So(其他) } Z { 分隔符; 细分为: Zs(空白)、Zl(行)、Zp(段落) }
Net 可支持字符集,譬如匹配简体中文: \p{ IsCJKUnifiedIdeographs}; 可惜当前版本暂不支持.
TRegex.Create('\P{P}');
Ok? Ok!-是吗?是的!
\P{} 是给 \p{} 取反; 这和 \D \S \W 是一样的.
TRegex.Create('\p{Nl}');
AⅠBⅡCⅢ
\p 实例: 匹配罗马数字
TRegex.Create('\p{Pi}');
“ABC” ‘abc’
\p 实例: 匹配前引号
TRegex.Create('\p{Pi}');
“ABC” ‘abc’
\p 实例: 匹配后引号
TRegex.Create('\p{Ps}');
(x)[x]{x}〈x〉《x》「x」『x』【x】〔x〕〖x〗
\p 实例: 匹配开始标点
TRegex.Create('\p{Pe}');
(x)[x]{x}〈x〉《x》「x」『x』【x】〔x〕〖x〗
\p 实例: 匹配结束标点
TRegex.Create('\p{Sc}');
$1 ¢2 £3 ¥4 ﹩5 $6 ¢7 £8 ¥9
\p 实例: 匹配货币符号
TRegex.Create('^Delphi');
Delphi Delphi Delphi
Delphi Delphi Delphi
^ 匹配行首; 在非多行模式下同 \A
TRegex.Create('^Delphi',[roMultiline]);
Delphi Delphi Delphi
Delphi Delphi Delphi
^ 在多行模式下
TRegex.Create('Delphi$');
Delphi Delphi Delphi
Delphi Delphi Delphi
$ 匹配行尾; 在非多行模式下同 \Z
TRegex.Create('Delphi$',[roMultiline]);
Delphi Delphi Delphi
Delphi Delphi Delphi
$ 在多行模式下
TRegex.Create('\ADelphi');
Delphi Delphi Delphi
Delphi Delphi Delphi
\A 匹配行首; 在多行模式下也是如此.
TRegex.Create('Delphi\Z');
Delphi Delphi Delphi
Delphi Delphi Delphi
\Z(或\z) 匹配行尾; 在多行模式下也是如此.
TRegex.Create('<.*>');
<html><head></head><body>ABC</body></html>
太贪婪了,一下子都匹配了; 这就是所谓的贪婪匹配,是默认的; 让匹配不贪婪只需要一个 ?
TRegex.Create('<.*?>');
<html><head></head><body>ABC</body></html>
这是非贪婪匹配,? 也叫惰性限制符;
* ? + {m} {m,n} {m,} 的本性都是贪婪的,都可以后缀一个 ? 成为非贪婪.
TRegex.Create('Delphi(?=20)');
Delphi7; Delphi2009; Delphi2010
(?=右边是); 这就是所谓的临界匹配,下续...
TRegex.Create('Delphi(?!20)');
Delphi7; Delphi2009; Delphi2010
(?!右边不是)
TRegex.Create('(?<=B)123');
A123,B123,C123
(?<=左边是)
TRegex.Create('(?<!B)123');
A123,B123,C123
(?<!左边不是); 如果 () 中不是临界匹配就是 "子表达式"
TRegex.Create('([A-Z])\w+');
one One two Two three FOUR
这是匹配首字母大写的英文单词,用到了子表达式; 其中的子表达式也同时匹配到了:
one One two Two three FOUR
如果不需要子表达式的匹配结果,可以在子表达式前加上 "?:",如: TRegex.Create('(?:[A-Z])\w+\'); 还可以通过 roExplicitCapture 选项来代替 ?: 的作用.
TRegex.Create('([A-Z])\w+',[roExplicitCapture]);
one One two Two three FOUR
但 roExplicitCapture 并不禁止用 ?<> 命名的子表达式获得匹配结果,如: TRegex.Create('(?<Name>[A-Z])\w+',[roExplicitCapture]); 有更多时候也需要子表达式的匹配结果,并且继续用于表达式中,还有多种使用方法.
TRegex.Create('([\w])\w+\1');
abba addr TNT _ABC_
子表达式可以有多个,可以在后面的表达式中用 \1 \2 \3 ...引用(这就是所谓的反向引用);
引用时要避免和八进制混淆,但避免的最好方法是使用其他方法引用.
TRegex.Create('(?<One>[\w])\w+\k<One>');
abba addr TNT _ABC_
这同上一例,只是给子表达式取名为 One,然后再用 \k<> 引用. 可以用单引号 ' 代替子表达式两边的 <>,不过这在 Delphi 中不方便,如:
TRegex.Create('(?''One''[\w])\w+\k''One''');Net 还支持 <序号>,此版本当前不支持. 另外子表达式还支持嵌套,序号次序从外向里.
TRegex.Create('(A)\d{3}|\d{4}');
A1,A12,A123,A1234,B1,B12,B1234
可利用子表达式执行类似 IfThen 的判断,这就是所谓的替换构造; 本例是:
假如首字母是 A 则匹配: 首字母外加三个数字; 反之则匹配: 首字母外加四个数字
TRegex.Create('cd(?#这是注释)e');
abcdefg
这是第一种注释方法
TRegex.Create('cde#这是注释',[roIgnorePatternWhitespace]);
abcdefg
这是第二种注释方法,只有打开 roIgnorePatternWhitespace 选项才能使用
TRegex.Create('Del phi',[roIgnorePatternWhitespace]);
万一的 Delphi 博客
这是忽略表示中空白的测试,它也同时忽略了查询目标的空白;
但有时会多匹配一个行首,不知是不是 bug.
TRegex.Create('(?i)Delphi|one|(?-i)two');
DELPHI ONE TWO
这是使用内联选项的测试; (?i)是忽略大小写,(?-i)是取消刚才的忽略.
譬如: (? ix-ms) 是启用 i 和 x 选项,同时取消 m 和 s 选项.
关于更多选项和内联选项参加后面的列表.
正则表达式选项列表:
roIgnoreCase(i) //不区分大小写 roMultiline(m) //多行模式; 它只是修改了 ^(行首) 和 $(行尾)的意义 roExplicitCapture(n) //不让子表达式获取匹配结果,类似 ?: 但它不禁止用 ?<> 命名的子表达式 roSingleline(s) //单行模式; 它只是修改了 . 的意义,使用后 . 也可以匹配换行符 roIgnorePatternWhitespace(x) //两个意思: 1、排除非转义空白; 2、启用 # 后面的注释 roStudy //同时编译表达式; 编译需要时间,但编译后执行就快了 { 其中的 i m n s x 是在表达式中直接调用这些选项的内联标记,roStudy 没有对应的标记 }