^(?!.*select).*$

 

3 分组捕获和替换
分组通常用来捕获特定模式的一组文本, 并用与之后的替换操作, 这也就是将分组和替换结合起来讲解的原因。最基本的分组构造方式就是(),在左右括号中括起来的部分,就是一个分组;在正则全集中还有如(? )的命名分组方式,这种方式组合了模式在就是对分组的部分进行了命名,这样就可以通过该组的命名来获取信息, 但这种方式在emeditor中不被支持。以下分别来介绍各种不同的分组:
() 组捕获。这种分组对模式在括号内所捕获的字符进行组合, 并且每个分组捕获的匹配结果都将保存为一个实体以备其后的操作所引用。甚至在正则全集中还可对前面的分组进行反向引用(这是题外话, emeditor不支持)。 举例说明:
源文本:
代码:
site status- online members: 65, online guests: 12
使用正则表达式:
代码:
(members|guests): 其后是冒号和一个空格, 最后匹配至少一个数字,匹配模式结果如下:
代码:
members: 65
guests: 12
其中members和guests在两次匹配中被捕捉, 可以在随后的操作中引用。

(?:) 非组捕获。这种分组仅仅对模式在括号内所匹配的字符进行组合, 模式所匹配的字符将不会作为一个组来捕获。虽然他也同样成为最终的匹配结果的一部分, 但无法为其后的操作所引用。同样以上例继续:
使用正则表达式:
代码:
(?:members|guests): \d+
匹配模式结果同样为:
代码:
members: 65
guests: 12
但是members和guests仅仅在两次匹配中被分组, 并不被捕获, 也不可以在随后的操作中引用。使用非捕获组有其原因和场合: 其一, 从效率上说, 捕获一个分组需要消耗额外的资源和处理时间, 所以不应该捕获不需要使用的数据。 其二, 对模式中有多个捕获组的情况, 对不需要处理的分组进行捕获只会对分组信息造成混乱。其三, 避免不需要贪婪匹配的场合发生贪婪匹配, 贪婪匹配是正则引擎的一个重要特性, 要说清楚其机理可能还需要另外开一个专题了。对这一点, 还以上例说明一下:
使用不带分组的正则表达式:
代码:
members|guests: \d+
匹配模式为:
代码:
members
guests: 12
这个正则表达式的问题在于, 他匹配的是"members" 或 "guests: \d+", 这是模式中贪婪"消费"字符引起的。而通过增加括号进行分组, 使正则引擎将两个匹配选项作为一个组处理, 从而正确匹配其中的一个匹配项。

(?=) 正声明组, 非捕获。此分组中的模式必须出现在声明的右侧, 并且, 这个模式不构成匹配结果的一部分。举例:
源文本:
代码:
site status- online members: 65, online guests: 12
使用正则表达式:
代码:
\S+(?=\s\d+)
此模式中规定了\s\d+必须出现在\S+声明的右侧。也就是说, 在至少一个非空格字符(声明)的右侧必须出现一个空格字符和至少一个数字, 而且只有这个声明构成匹配结果。匹配模式结果如下:
代码:
members:
guests:
这两次匹配中不被捕捉。

(?!) 负声明组, 非捕获。此分组中的模式不得出现在声明的右侧, 并且, 这个模式不构成匹配结果的一部分。还是用上面的例子:
使用正则表达式:
代码:
\d{2}(?!,)
此模式中规定了","不得出现在\d{2}声明的右侧。也就是说, 在连续两个数字(声明)的右侧不得出现逗号才能被匹配。匹配模式结果如下:
代码:
12
这两次匹配中不被捕捉。严格的说, 后面两个分组不能称之为分组, 他们只是模式声明, 他们不能成为匹配结果, 也不能被捕获。在正则全集中, 还有反向声明分组(?<=)(?), 在emeditor中不被支持。说到括号的功能, 本来正则中的一个重要指令-条件指令和分组内联设定是不得不说的, 可惜的是Emeditor也同样不支持。在前面的例子中一直提到匹配之后的操作, 而这个进一步的操作最常见的就是替换。先继续上面的例子:
源文本:
代码:
site status- online members: 65, online guests: 12
使用搜索正则表达式:
代码:
(members|guests)
和替换正则表达式:
代码:
ccf-\1
匹配模式结果如下:
代码:
members
guests
替换后的文本为:
代码:
site status- online ccf-members: 65, online ccf-guests: 12
其中members和guests在两次匹配中被捕捉, 在随后被引用, 并添加ccf-前缀后替换源文本中的匹配字符。在匹配模式中的分组匹配结果将按前后顺序被正则引擎分别赋予内部组号, 在替换操作中就可以用\加上这个组号来引用相应的匹配结果。继续上例:
使用搜索正则表达式:
代码:
(members|guests): (\d{2})
和替换正则表达式:
代码:
ccf-\1 = \2
匹配模式结果如下:
代码:
members: 65
guests: 12
替换后的文本为:
代码:
site status- online ccf-members = 65, online ccf-guests = 12
在emeditor的正则子集中增加了一个特殊的引用: \0 , \0 将引用上次的匹配结果, 继续把:
使用搜索正则表达式:
代码:
\d{2}
和替换正则表达式:
代码:
*\0*
匹配模式结果如下:
代码:
65
12
替换后的文本为:
代码:
site status- online ccf-members: *65*, online ccf-guests: *12*