推荐一个专门用于编写正则表达式的网站:
regex101: build, test, and debug regex
参考文档:
https://zh.wikipedia.org/wiki/%E6%AD%A3%E5%88%99%E8%A1%A8%E8%BE%BE%E5%BC%8F
^ : 表示字符串的开头
例子: "abc"用"^a"匹配可以匹配出"a",而”bac"用^a匹配,则无法匹配成功。
$ : 表示字符串的结尾
例子:“abc"用”c$"匹配可以匹配出"c",而“acb"用“c$”匹配,则无法匹配成功。
+:表示匹配前面的字符1个~无限个(贪婪模式下会尽可能匹配多个字符,如果要用非贪婪模式,则要用”+?“)
例子:“abbc"用”ab+"匹配可以匹配出"abb"。“aabc"用“ab+”匹配可以匹配出"ab"。而”acc"用“ab+”匹配,则无法匹配成功。
*:表示匹配前面的字符0个~无限个(贪婪模式下会尽可能匹配多个字符,如果要用非贪婪模式,则要用”+?“)
例子:“abbc"用”ab*"匹配可以匹配出"abb"。“aabc"用“ab*”匹配可以匹配出"ab"。而”acc"用“ab*”匹配,可以匹配出“a"。
?:表示匹配前面的字符0个或者1个
例子:“abc"用”ab?"匹配可以匹配出"ab"。“ac"用“ab?”匹配可以匹配出"a"。
{2,4}:表示匹配前面的字符2个到4个,而{2,}则表示2个到无穷个
例子:”abbbb“用"b{2,3}"匹配可以匹配出”abbb“, "ab"用"b{2,3}"匹配,则无法匹配成功|
| : 表示“或”的意思
例子1:”ac“用"a|b"匹配可以匹配出”a“, ”bc“用"a|b"匹配可以匹配出”b“,而“cd”用"a|b"匹配,则无法匹配成功
例子2:”dabcd“用"abc|qwe"匹配可以匹配出”abc“,
例子3:”abcwe“用"ab(c|q)we"匹配可以匹配出”abcwe“,
[abc]:表示只要是中括号内的字符都可以匹配到,
[a-zA-Z0-9],则表示匹配大小写字母以及数字字符
例子:"abc"用[b]匹配,可以匹配出”b",”abc"用[bc]匹配,则可以匹配出"b“和”c"
[^abc]:则表示除开中括号内的字符都可以匹配到
例子:"abc"用[^b]匹配,可以匹配出”a"和“c”,”abc"用[^bc]匹配,则可以匹配出"a“
\ :反斜杠,转义字符
. :匹配除“\r
”“\n
”之外的任何单个字符。要匹配包括“\r
”“\n
”在内的任何字符,请使用像“(.|\r|\n)
”的模式
例子:"abc"用 . 匹配,可以匹配出”a"和“b“和“c”
\w:匹配字母、数字和下划线
\W:匹配除开字母、数字和下划线的所有字符
例子:"a&1_"用 \w 匹配,可以匹配出”a"和“1“和“_”,"a&1_"用 \W 匹配,可以匹配出”&"
\d:匹配数字字符
\D:匹配数字以外的字符
例子:"a&1_"用 \d 匹配,可以匹配出“1“,"a&1_"用 \D 匹配,可以匹配出"a"和”&"和”_"
\s:匹配空格和换行
\S:匹配除开空格和换行以外的字符
例子:"a c"用 \s 匹配,可以匹配出“ “,"a c"用 \S 匹配,可以匹配出"a"和”c"
():用小括号括起来表示一个group,这样方便我们对字符串内的某些子串进行提取
例子:“ab_11"用"(([a-z]+)_(\d+))"进行匹配,group 1就是“ab_11”, group 2就是”ab“,group 3就是”11“
代码:
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"(([a-z]+)_(\d+))";
string input = @"ab_11";
RegexOptions options = RegexOptions.Multiline;
foreach (Match m in Regex.Matches(input, pattern, options))
{
Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index);
}
}
}
害羞群组(shy group):
(?: ) : 在小括号里的前端加入?:,则当前这个小括号匹配到的内容不会加入到群组中
例子:
例子:“ab_11"用”((?:[a-z]+)_(\d+))“进行匹配,group1就是“ab_11”,group2就是”11“,可以发现“ab”已经不在群组里了。
代码:
using System;
using System.Text.RegularExpressions;
public class Example
{
public static void Main()
{
string pattern = @"((?:[a-z]+)_(\d+))";
string input = @"ab_11";
RegexOptions options = RegexOptions.Multiline;
foreach (Match m in Regex.Matches(input, pattern, options))
{
Console.WriteLine("'{0}' found at index {1}.", m.Value, m.Index);
}
}
}
反向引用 (Backreferences):
\1 : 表示匹配group1的值(匹配的时候用\1,当使用regex.Replace的时候,\1要改成$1)
例子:“abc=def,abc=abc,def=abc,def=def”用“(abc|def)=\1”匹配,则会匹配到"abc=abc"和"def=def"。这里的\1就是群组1(group1)的值
平衡组相关:
(?'name') :对一个群组进行命名,并且把对应数据压入"name"栈(Stack)
例子:“ab_11"用"((?'name'[a-z]+)_(\d+))"进行匹配,group 1就是“ab_11”, group name就是”ab“,group 3就是”11“
(?'-name') 从堆栈上弹出最后压入堆栈的名为name的捕获内容,如果堆栈本来为空,则本分组的匹配失败
(?(name)yes|no) 如果堆栈上存在以名为group的捕获内容的话,继续匹配yes部分的表达式,否则继续匹配no部分
(?!) 顺序否定环视,由于没有后缀表达式,试图匹配总是失败
推荐一个平衡组相关教程:正则表达式——详细讲解平衡组_zm2714的博客-CSDN博客_正则平衡组
左右合样(Lookaround):
右肯定合样:
例子:“ab”用“a(?=b)”匹配可以匹配到"a","ac"用"a(?=b)",则无法匹配成功
("a(?=b)"表示a后面一定要是b,但是b并不会被加到匹配结果里面)
右否定合样:
例子:“ac”用“a(?!b)”匹配可以匹配到"a","ab"用"a(?!b)",则无法匹配成功
("a(?!b)"表示a后面一定不能是b)
左肯定合样:
例子:“ab”用“(?<=a)b”匹配可以匹配到"b","cb"用"(?<=a)b",则无法匹配成功
("(?<=a)b"表示b前面一定要是a,但是a并不会被加到匹配结果里面)
左否定合样:
例子:“cb”用“(?
("(?
例子:
"aaabab"用"a.*b"匹配会匹配到”aaabab"。(尽可能多的匹配)
"aaabab"用"a.*?b"匹配会匹配到“aaab”。(尽可能少的匹配)
推荐一个视频:
深入浅出正则表达式_哔哩哔哩_bilibili