在 Visual Studio (VS2015)中搜索时使用正则表达式
目录
- 一、基本规则
- 1. 字符匹配
- 2. 字符类
- 3. 定位符
- 4. 限定符
- 5. 分组和反向引用
- 6. 选择符
- 二、高级用法
- 1. 非贪婪模式
- 2. 前瞻和后顾断言
- 3. 转义字符
- 三、示例场景
- 1. 匹配电子邮件地址
- 2. 匹配电话号码(包括国际格式)
- 3. 匹配URL
- 4. 匹配日期(YYYY-MM-DD)
- 5. 匹配IP地址(IPv4)
- 6. 匹配HTML标签
- 7. 匹配特定格式的单词
- 8. 匹配特定长度的字符串
- 9. 匹配由特定字符分隔的字符串
- 10. 匹配不包含特定字符的字符串
- 其他示例
在Visual Studio 2015(VS2015)中,使用搜索(通常是查找和替换功能)时,可以启用正则表达式模式来执行更复杂的文本匹配和替换操作。开启的话只需要在查找和替换对话框中,勾选“ 使用正则表达式”选项。
以下是正则表达式的一些基本规则和常见用法:
一、基本规则
1. 字符匹配
- 大多数普通字符(如字母、数字、标点符号等)在正则表达式中直接表示它们自身。
- 特殊字符(如
.
、*
、?
、+
、|
、(
、)
、[
、]
、{
、}
、^
、$
、\
等)在正则表达式中具有特殊含义,如果要匹配这些字符本身,需要使用反斜杠\
进行转义。
2. 字符类
[xyz]
:匹配方括号中的任意一个字符。[^xyz]
:匹配不在方括号中的任意字符。[a-z]
:匹配指定范围内的任意字符(例如,小写字母)。[A-Z]
:匹配大写字母。[0-9]
:匹配数字,等价于\d
。\w
:匹配字母、数字、下划线,等价于[A-Za-z0-9_]
。\W
:匹配非字母、数字、下划线,等价于[^A-Za-z0-9_]
。
3. 定位符
^
:匹配输入字符串的开始位置。在多行模式下,也匹配每行的开始。$
:匹配输入字符串的结束位置。在多行模式下,也匹配每行的结束。\b
:匹配单词边界,即单词字符(\w
)和非单词字符之间的位置。换句话说,它匹配一个单词的开始或结束位置。例如,正则表达式
\bapple\b
将匹配文本 “I ate an apple.” 中的 “apple”,但不会匹配 “apples” 或 “pineapple”。\B
:匹配非单词边界。
4. 限定符
-
*
:匹配前面的子表达式零次或多次。例如,正则表达式 abc 可以匹配以下字符串:
“ac”(因为 b 出现了零次)
“abc”(因为 b 出现了一次)
“abbc”(因为 b 出现了两次)
“abbbc”(因为 b 出现了三次)
需要注意的是, 是贪婪的,它会尽可能多地匹配字符。如果你希望进行非贪婪匹配(即尽可能少地匹配字符),可以使用*?
。例如,正则表达式a.*?c
会匹配字符串 “axyzc” 中的 “axc”,而不是整个字符串。 -
+
:匹配前面的子表达式一次或多次。 -
?
:匹配前面的子表达式零次或一次。 -
{n}
:n是一个非负整数,匹配确定的n次。例如,正则表达式 a{3} 将匹配字符串 “aaa”,但不会匹配 “aa” 或 “aaaa”。请注意,如果你需要匹配大括号字符 { 和 } 本身,你需要对它们进行转义,如 \{ 和 \}。
-
{n,}
:n是一个非负整数,至少匹配n次。例如,假设我们有以下正则表达式:
a{2,}
这个正则表达式将匹配以下字符串:
“aa”
“aaa”
“aaaa”
“aaaaa”
但它不会匹配以下字符串:
“a”(因为它只出现了一次,而我们需要至少两次)
“b”(因为它不包含字符 “a”) -
{n,m}
:m和n均为非负整数,其中n<=m,匹配至少n次且不超过m次。例如,如果有一个正则表达式
a{2,4}
,它将匹配:
“aa”(a 出现了 2 次)
“aaa”(a 出现了 3 次)
“aaaa”(a 出现了 4 次)
但是,它不会匹配:
“a”(a 只出现了 1 次,少于最小次数 2)
“aaaaa”(a 出现了 5 次,超过了最大次数 4)
5. 分组和反向引用
-
()
:将正则表达式的一部分放在圆括号中,形成一个捕获组。捕获组可以整体处理,也可以通过\n
(n是一个数字,表示第n个捕获组)进行反向引用。这种结构使得我们可以方便地提取匹配到的数据,或者在后续的正则表达式中重复使用已经匹配到的部分。
例如,在正则表达式(\d{4})-(\d{2})-(\d{2})
中,我们使用了三个捕获组来匹配日期格式YYYY-MM-DD:
第一个捕获组(\d{4})
匹配年份
第二个捕获组(\d{2})
匹配月份
第三个捕获组(\d{2})
匹配日期
通过捕获组,我们可以方便地提取出年、月、日这三个部分,并在后续的处理中使用它们。同时,如果我们需要在同一个正则表达式中重复使用某个捕获组匹配到的内容,可以使用 \n 进行反向引用。例如,\1 表示第一个捕获组匹配到的内容,\2 表示第二个捕获组匹配到的内容,以此类推。
6. 选择符
|
:表示“或”关系,匹配|
左右两边的表达式之一。
二、高级用法
1. 非贪婪模式
- 默认情况下,正则表达式的
*
、+
、?
等限定符是贪婪的,即它们会尽可能多地匹配字符。通过在限定符后添加?
,可以将其转换为非贪婪模式(也称为懒惰模式),即尽可能少地匹配字符。例如,在匹配字符串 “aaab” 时,如果使用贪婪模式的正则表达式
a+
,它会匹配到最长的子串 “aaa”。但如果使用非贪婪模式的正则表达式a+?
,它只会匹配到第一个 “a”,因为非贪婪模式会优先匹配最少的字符。
2. 前瞻和后顾断言
正则表达式支持前瞻(lookahead)和后顾(lookbehind)断言,用于匹配某个位置,但不消耗(即不移动匹配指针)任何字符。
-
前瞻断言:
(?=exp)
(正向前瞻)、(?!exp)
(负向前瞻)。正向前瞻它表示,只有当后面的字符序列与括号内的正则表达式匹配时,才会认为当前位置是匹配的。假设你想匹配一个数字,后面紧跟着一个百分号(%)。你可以使用正向前瞻来实现这个需求:
\d+(?=%)
在这个例子中,\d+ 匹配一个或多个数字,(?=%) 是一个正向前瞻,它检查后面是否紧跟着一个百分号。如果条件满足,则整个表达式匹配成功。负向前瞻它表示,只有当后面的字符序列与括号内的正则表达式不匹配时,才会认为当前位置是匹配的。假设你想匹配一个单词,但它后面不能紧跟着 “ing” 形式的后缀。你可以使用负向前瞻来实现这个需求:
\b\w+(?!\b\w*ing\b)
在这个例子中,\b\w+
匹配一个单词,(?!\b\w*ing\b)
是一个负向前瞻,它检查后面是否紧跟着 “ing” 形式的后缀。如果条件不满足(即后面没有 “ing” 后缀),则整个表达式匹配成功。需要注意的是,前瞻断言只是用于检查后续字符序列,并不会消耗这些字符。因此,在使用前瞻断言时,需要确保正则表达式的其余部分能够正确匹配所需的字符序列。
-
后顾断言(注意:并非所有正则表达式引擎都支持后顾断言):
(?<=exp)
(正向后顾)、(?<!exp)
(负向后顾)。后顾断言在处理字符串匹配时非常有用,尤其是在需要根据字符串中特定位置前后的文本来确定是否进行匹配的场景中。
正向后顾断言用于检查当前匹配位置之前的文本是否满足某个模式,但不会将这个模式包含在最终的匹配结果中。例如,假设我们有以下文本:
这件衣服的价格是100元,而那件衣服的价格是200元。
如果我们想要匹配“价格”之后的数字,可以使用正向后顾断言:
(?<=价格)\d+
匹配了“价格”后面的数字“100”和“200”。负向后顾断言用于检查当前匹配位置之前的文本是否不满足某个模式,同样不会将这个模式包含在最终的匹配结果中。例如,假设我们有以下文本:
编号123,价格10
如果我们想要匹配不在“价格”之后的数字,可以使用负向后顾断言:
(?<!价格)\d+
input:“编号123,价格10。”
匹配了不在“价格”后面的数字“123”。注意,“价格”后面的“10”没有被匹配,因为它紧跟在“价格”之后。
3. 转义字符
- 在正则表达式中,如果要匹配特殊字符本身(如
.
、*
、?
等),需要使用反斜杠\
进行转义。但在某些情况下,如果反斜杠本身也需要被匹配,则需要使用\\
来表示。
三、示例场景
1. 匹配电子邮件地址
^[\w-\.]+@([\w-]+\.)+[\w-]{2,4}$
说明:这个表达式用于匹配简单的电子邮件地址。它假设电子邮件地址由字母、数字、下划线和短横线组成,后面跟着@
符号,然后是域名部分(由点分隔的多个部分),最后是顶级域名(2到4个字符)。
2. 匹配电话号码(包括国际格式)
^\+?(\d{1,3}\s?)?[\(]?\d{3}[\)]?[\s\-]?\d{3}[\s\-]?\d{4}$
说明:这个表达式可以匹配多种格式的电话号码,包括可选的国际码(+
开头,后面可能跟着1到3位数字,可能有空格)、可选的括号包围的区号、可选的空格或短横线分隔的数字组。
3. 匹配URL
\bhttps?:\/\/[^\s()<>]+(?:\([\w\d]+\)|([^[:punct:]\s]|/))
说明:这个表达式用于匹配HTTP和HTTPS协议的URL。它考虑了协议前缀(http或https,可选的s表示安全连接)、域名部分(不包括特殊字符和空格)以及可选的端口号或路径。
4. 匹配日期(YYYY-MM-DD)
\b\d{4}-\d{2}-\d{2}\b
说明:这个表达式匹配格式为“年-月-日”的日期,其中年、月、日分别为4位、2位、2位数字。
5. 匹配IP地址(IPv4)
\b(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b
说明:这个表达式用于匹配IPv4地址。它分别匹配四个0到255之间的数字,每个数字之间用点.
分隔。
6. 匹配HTML标签
<[^>]+>
说明:这个简单的表达式匹配任何HTML标签,从<
开始,直到遇到第一个>
结束。
7. 匹配特定格式的单词
\b\w*example\w*\b
说明:这个表达式匹配包含“example”的单词,其中“example”前后可以有任意数量的字母、数字或下划线。
8. 匹配特定长度的字符串
^\w{8,16}$
说明:这个表达式匹配长度在8到16个字符之间的字符串,字符串只能包含字母、数字或下划线。
9. 匹配由特定字符分隔的字符串
(\w+)[:,]\s*(\w+)
说明:这个表达式匹配由逗号,
或冒号:
分隔的两个单词或字符串,每个单词前后可以有任意数量的空格。
10. 匹配不包含特定字符的字符串
^[^aeiou]+$
说明:这个表达式匹配不包含任何元音字母(a、e、i、o、u)的字符串。
其他示例
- 匹配信用卡号:
\b\d{13,19}\b
(注意:这只是一个非常简单的示例,实际的信用卡号验证会更复杂) - 匹配社交安全号码(SSN):
\b\d{3}-\d{2}-\d{4}\b
- 匹配时间(HH:MM:SS):
\b\d{2}:\d{2}:\d{2}\b
- 匹配邮政编码(美国):
\b\d{5}(-\d{4})?\b
- 匹配HTML注释:
<!--.*?-->
(非贪婪模式) - 匹配空白行:
^\s*$
- 匹配C语言风格的注释:
\/*.*?*\/
(注意:这通常需要在支持多行模式的正则表达式引擎中使用)