正则表达式
正则表达式 是一种匹配输入文本的模式。.Net 框架提供了允许这种匹配的正则表达式引擎。模式由一个或多个字符、运算符和结构组成。
作用:
- 查询,从字符串中获取我们想要的部分
- 匹配,判定字符串是否符合规则
如判断用户输入的密码是否正确,邮箱格式是否合法等。
字符转义
正则表达式中的反斜杠字符(\)指示其后跟的字符是特殊字符,或应按原义解释该字符。
- \u nnnn 匹配的 UTF-16 代码单元,单元值是 nnnn 十六进制。
- \a 匹配响铃(警报)字符,\u0007。
- \b 在 [character_group] 字符类中,匹配退格,\u0008。
- \t 匹配制表符,\u0009。
- \n 匹配换行,\u000A。
- \r 匹配回车,\u000D。 请注意,\r 不等同于换行符,\n。
- \v 匹配垂直制表符,\u000B。
- \f 匹配换页,\u000C。
- \e 匹配转义,\u001B。
- \ nnn 匹配 ASCII 字符,其中 nnn 包含表示八进制字符代码的两位数或三位数。 例如,\040 表示空格字符。 如果此构造仅包含一个数字(如 \2)或者它对应捕获组的编号,则将它解释为向后引用。 (请参阅向后引用构造。)
- \x nn 匹配 ASCII 字符,其中 nn 是两位数的十六进制字符代码。
- \c X 匹配 ASCII 控制字符,其中 X 是控制字符的字母。 例如,\cC 为 CTRL-C。
- \ 后接字符未识别为转义字符时,将匹配此字符。 例如,* 匹配星号 (*) 并等同于 \x2A。
示例:
string content = "E\u0009rror!\n123";
Console.WriteLine(content);
输出:
//E rror!
//123
字符类
字符类与一组字符中的任何一个字符匹配。
- 正字符组 ,与[ ] 字符集中的任何单个字符匹配。 默认情况下,匹配区分大小写。 [mn] “mat” 中的 “m”,“moon” 中的 “m” 和 “n”
- 负字符组,与不在[^]中的任何单个字符或者一个范围匹配。 默认情况下, 字符集 中的字符区分大小写。 [^aei] “reign” 中的 “r”、“g” 和 “n”
- [first-last] 字符范围:与从第一个至最后一个的范围内的任何单个字符匹配。 [A-Z] “AB123” 中的 “A” 和 “B”
- . 通配符:与除 \n 之外的何单个字符配。若要匹配文本句点字符(. 或 \u002E),你必须在该字符前面加上转义符 (.)。 a.e “nave” 中的 “ave” “water” 中的 “ate”
- \p{name} 与不在 name 指定的 Unicode 通用类别或命名块中的任何单个字符匹配。 \P{Lu} \P{IsCyrillic} “City” 中的 “i”、“t” 和 “y” “ДЖem” 中的 “e” 和 “m”
- \w 与任何单词字符匹配。 \w “ID A1.3” 中的 “I”、“D”、“A”、“1” 和 “3”; 单词字符通常包括字母(a-zA-Z)、数字(0-9)以及下划线(_)
- \W 与任何非单词字符匹配。 \W “ID A1.3” 中的 " " 和 “.”
- \s 与任何空白字符匹配。 \w\s “ID A1.3” 中的 "D "
- \S 与任何非空白字符匹配。 \s\S “int __ctr” 中的 " _"
- \d 与任何十进制数字匹配。 \d “4 = IV” 中的 “4”
- \D 与任何不是十进制数的字符匹配。 \D “4 = IV” 中的 " “、”=“、” "、“I” 和 “V”
提示:@可以用于取消转义。字符串前面加上@符号用于表示这是一个逐字字符串(verbatim string literal),它告诉编译器在这个字符串中的反斜杠\应该被当作普通字符而不是转义字符的开始。
示例:
//正字符组:[ ]
// 要匹配的字符串内容
string content1 = "abcd";
// 正则表达式,前面加上@可以去除转义
string RegexStr = @"[ac]";
// 使用Matches()匹配字符集
MatchCollection ms = Regex.Matches(content1, RegexStr);
//遍历所有匹配的字符
foreach (Match match in ms) { Console.WriteLine(match); }
//输出:ac
//负字符组:[^]
string content2 = "123abc";
string RegexStr2 =@"[^0-9]";//除去0到9的所有数字
MatchCollection ms2=Regex.Matches(content2, RegexStr2);
foreach (Match item in ms2) { Console.Write(item); }
//输出:abc
定位点
定位点或原子零宽度断言会使匹配成功或失败,具体取决于字符串中的当前位置,但它们不会使引擎在字符串中前进或使用字符。
- ^ 默认情况下,必须从字符串的开头开始匹配;在多行模式中,必须从该行的开头开始。 ^\d{3} “901-333-” 中的 “901”
- $ 默认情况下,匹配必须出现在字符串的末尾,或在字符串末尾的 \n 之前;在多行模式中,必须出现在该行的末尾之前,或在该行末尾的 \n 之前。 -\d{3}$ “-901-333” 中的 “-333”
- \A 匹配必须出现在字符串的开头。 \A\d{3} “901-333-” 中的 “901”
- \Z 匹配必须出现在字符串的末尾或出现在字符串末尾的 \n 之前。 -\d{3}\Z “-901-333” 中的 “-333”
- \z 匹配必须出现在字符串的末尾。 -\d{3}\z “-901-333” 中的 “-333”
- \G 匹配必须在上一个匹配结束的位置进行;如果以前没有匹配项,则从开始进行匹配的字符串中的位置开始。 \G(\d) “(1)(3)(5)7” 中的 “(1)”、“(3)” 和 “(5)”
- \b 匹配必须出现在 \w (字母数字)和 \W (非字母数字)字符之间的边界上。 \b\w+\s\w+\b “them theme them them” 中的 “them theme” 和 “them them”
- \B 匹配不得出现在 \b 边界上。 \Bend\w*\b “end sends endure lender” 中的 “ends” 和 “ender”
示例:
Console.WriteLine("输入三个数字:");
string content3=Console.ReadLine();
string RegexStr3 = @"^\d{3}\b";
if (Regex.IsMatch(content3, RegexStr3))
{
Console.WriteLine("Ok");
}
else
{
Console.WriteLine("输入不合法!");
}
分组构造
分组构造描述了正则表达式的子表达式,通常用于捕获输入字符串的子字符串。
1.匹配的子表达式
以下分组构造捕获匹配的子表达式:
( subexpression )
示例
//分组构造:
string content4 = "Boo222m_Boom_";
//捕获所有数字
string RegexStr4 = @"(\d)";
MatchCollection ms4=Regex.Matches(content4, RegexStr4);
foreach (var item in ms4)
{
Console.WriteLine(item);
}
输出:
//2
//2
//2
2.命名匹配的子表达式
以下分组构造捕获匹配的子表达式,并允许你按名称或编号访问它:
(?< name>subexpression)
或:
(?'name'subexpression)
访问已命名的捕获组:
- 使用语法 \k
在同一正则表达式中引用匹配的子表达式,其中 name 是捕获子表达式的名称。 - \数字在同一正则表达式中引用匹配的子表达式,其中 数字 是捕获的表达式的初始数字。 已命名的匹配子表达式在匹配子表达式后从左到右连续编号。
- 通过使用 GroupCollection 对象的方式,该对象由 Match.Groups 属性返回。 集合中位置零上的成员表示正则表达式匹配。 每个后续成员表示匹配的子表达式。 已命名的捕获组在集合中存储在已编号的捕获组后面。
限定符
限定符指定在输入字符串中必须存在上一个元素(可以是字符、组或字符类)的多少个实例才能出现匹配项。 限定符包括下表中列出的语言元素。
- ** 匹配上一个元素零次或多次。 a.*c “abcbc” 中的 “abcbc”
- + 匹配上一个元素一次或多次。 “be+” “been” 中的 “bee”、“bent” 中的 “be”
- ? 匹配上一个元素零次或一次。 “rai?” “rain” 中的 “rai”
- {n} 匹配上一个元素恰好 n 次。 “,\d{3}” “1,043.6” 中的 “,043”、“9,876,543,210” 中的 “,876”、“,543” 和 “,210”
- {n,} 匹配上一个元素至少 n 次。 “\d{2,}” “166”, “29”, “1930”
- {n,m} 匹配上一个元素至少 n 次,但不多于 m 次。 “\d{3,5}” “166”, “17668” “193024” 中的 “19302”
- ? 匹配上一个元素零次或多次,但次数尽可能少。 a.?c “abcbc” 中的 “abc”
- +? 匹配上一个元素一次或多次,但次数尽可能少。 “be+?” “been” 中的 “be”、“bent” 中的 “be”
- ?? 匹配上一个元素零次或一次,但次数尽可能少。 “rai??” “rain” 中的 “ra”
- {n}? 匹配前面的元素恰好 n 次。 “,\d{3}?” “1,043.6” 中的 “,043”、“9,876,543,210” 中的 “,876”、“,543” 和 “,210”
- {n,}? 匹配上一个元素至少 n 次,但次数尽可能少。 “\d{2,}?” “166”, “29” 和 “1930”
- {n,m}? 匹配上一个元素的次数介于 n 和 m 之间,但次数尽可能少。 “\d{3,5}?” “166”, “17668” “193024” 中的 “193” 和 “024”
反向引用构造
反向引用允许在同一正则表达式中随后标识以前匹配的子表达式。
1.带编号的反向引用
带编号的反向引用使用以下语法:
\number
其中 number 是正则表达式中捕获组的序号位置
示例:
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
// \1匹配值与第一捕获组相同的下一个字符。
string pattern = @"(\w)\1";
string input = "trellis llama webbing dresser swagger";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("Found '{0}' at position {1}.",
match.Value, match.Index);
}
}
// The example displays the following output:
// Found 'll' at position 3.
// Found 'll' at position 8.
// Found 'bb' at position 16.
// Found 'ss' at position 25.
// Found 'gg' at position 33.
2.命名的反向引用
使用以下语法定义命名的反向引用:
\k< name >
或:
\k' name '
示例:
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(?<char>\w)\k<char>";
string input = "trellis llama webbing dresser swagger";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("Found '{0}' at position {1}.",
match.Value, match.Index);
}
}
// The example displays the following output:
// Found 'll' at position 3.
// Found 'll' at position 8.
// Found 'bb' at position 16.
// Found 'ss' at position 25.
// Found 'gg' at position 33.
3.已命名数值的反向引用
在具有 \k 的已命名反向引用中,name 也可以是 number 的字符串表示形式\k。
示例:
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(?<2>\w)\k<2>";
string input = "trellis llama webbing dresser swagger";
foreach (Match match in Regex.Matches(input, pattern))
Console.WriteLine("Found '{0}' at position {1}.",
match.Value, match.Index);
}
}
// The example displays the following output:
// Found 'll' at position 3.
// Found 'll' at position 8.
// Found 'bb' at position 16.
// Found 'ss' at position 25.
// Found 'gg' at position 33.
如果 name 是 number 的字符串表示形式,且没有捕获组具有该名称,\k< name > 与反向引用 \number 相同,其中 number 是捕获的序号位置。string pattern = @"(?<2>\w)\k<2>"可以写为string pattern = @"(?<2>\w)\2";
4.反向引用匹配什么内容
反向引用引用组的最新定义(从左向右匹配时,最靠近左侧的定义)。 当组建立多个捕获时,反向引用会引用最新的捕获。
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(?<1>a)(?<1>\1b)*";
string input = "aababb";
foreach (Match match in Regex.Matches(input, pattern))
{
Console.WriteLine("Match: " + match.Value);
foreach (Group group in match.Groups)
Console.WriteLine(" Group: " + group.Value);
}
}
}
// The example displays the following output:
// Group: aababb
// Group: abb
在比较正则表达式与输入字符串(“aababb”)时,正则表达式引擎执行以下操作:
-
从该字符串的开头开始,成功将“a”与表达式 (?<1>a) 匹配。 此时,1 组的值为“a”。
-
继续匹配第二个字符,成功将字符串“ab”与表达式 \1b 或“ab”匹配。 然后,将结果“ab”分配到 \1。
-
继续匹配第四个字符。 表达式 (?<1>\1b)* 要匹配零次或多次,因此会成功将字符串“abb”与表达式 \1b 匹配。 然后,将结果“abb”分配回到 \1。
在本示例中,* 是循环限定符 -- 它将被重复计算,直到正则表达式引擎不能与它定义的模式匹配为止。 循环限定符不会清除组定义。
备用(替换)构造
备用构造用于修改正则表达式以启用 either/or 匹配。
1.利用 | 的模式匹配:
- 使用 | 字符的正则表达式 \bgr(a|e)y\b;(a|e)等同于[ae]
- 正则表达式 \b(\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b;匹配两个数字开头或者三个数字开头的不同格式的9位数
2.条件匹配的表达式
(?( expression ) yes | no )
其中,expression 是要匹配的初始模式,yes 是当 expression 匹配时要匹配的模式,而 no 是 expression 不匹配时要匹配的可选模式(如果未提供 no 模式,则其等效于一个空 no)。
正则表达式模式 \b(?(\d{2}-)\d{2}-\d{7}|\d{3}-\d{2}-\d{4})\b
- \b 在单词边界处开始。
- (?(\d{2}-) 确定接下来的三个字符是否由两个数字后接一个连字符组成。
- \d{2}-\d{7} 如果前面的模式匹配,则匹配后接一个连字符和七个数字的两个数字。
- \d{3}-\d{2}-\d{4} 如果前面的模式不匹配,则匹配三个十进制数字,后接一个连字符,再接两个十进制数字,再接另一个连字符,再接四个十进制数字。
- \b 与字边界匹配。
3.基于有效的捕获组的条件匹配
正则表达式模式 \b(?
- \b 在单词边界处开始。
- (?
\d{2}-)? 匹配两个数字后接一个连字符的零或一个匹配项。 命名此捕获组 n2。 - (?(n2) 测试输入字符串中是否有 n2 的匹配项。
- \d{7} 如果找到 n2 的匹配项,则匹配 7 个十进制数字。
- |\d{3}-\d{2}-\d{4} 如果未找到 n2 的匹配项,则匹配 3 个十进制数字,后接一个连字符,再接 2 个十进制数字,再接另一个连字符,再接 4 个十进制数字。
- \b 与字边界匹配。
替换
替换是替换模式中使用的正则表达式。
标签:字符,匹配,string,正则表达式,字符串,Found From: https://www.cnblogs.com/comradexiao/p/18473901