C# 正则表达式
Regex.Match(input,beging,length)
string str="01234567_89";
Regex regexBracket=new Regex(@"_",RegexOptions.RightToLeft);
Match match=regexBracket.Match(str,8,1);//beging和length分别指范围的左和右,不管是不是右向左匹配RegexOptions.RightToLeft
Debug.Log(match.Success);//output: true
移除空白
string myString = " this\n is\r a \ttest ";
Console.WriteLine(Regex.Replace(myString, @"\s", ""));
string text="using System. Collections .Generic;";
Regex removeWhiteRegex=new Regex(@"\s",RegexOptions.Compiled);
string result=removeWhiteRegex.Replace(text,"");
Debug.Log(result);//output:using System.Collections.Generic;
匹配3个 "任意字符."
string text=" System.Collections.你好123.Generic;";
Regex regex=new Regex(@"(\w+\.){3}",RegexOptions.Compiled);
Match match=regex.Match(text);
if(match.Success){
Debug.Log(match.Value);//output: System.Collections.你好123.
}
捕获组:
语法如下:
普通捕获组:(Expression)
命名捕获组:(?<name>Expression)
引用命名捕获组:\k<name>,如: string pattern = @"\b(?<word>\w+)\s+(\k<word>)\b";
捕获组编号规则:
编号为0的捕获组,指的是正则表达式整体,一般不用。
如正则表达式:string pattern = @(\d{4})-(\d{2}-(\d\d));
编号 | 捕获组 | 匹配内容 |
---|---|---|
0 | (\d{4})-(\d{2}-(\d\d)) | 2008-12-31 |
1 | (\d{4}) | 2008 |
2 | (\d{2}-(\d\d)) | 12-31 |
3 | (\d\d) | 31 |
Match match = Regex.Match(input, pattern);
//match .Groups[1].Captures
//C#中的Group只表示所有捕获Captures的最后一项
// 示例:查找"_"分隔的数字,及命名分组的使用
// (?<name>subexpression) 或 (? 'name'subexpression)
string str = "Item10_18";
Regex reg = new Regex(@"(?<pageIndex>\d+)_(?<itemIndex>\d+)", RegexOptions.Compiled);
Match match = reg.Match(str);
if (match.Success) {
Debug.Log(match.Groups["pageIndex"]); // 输出:"10"
Debug.Log(match.Groups["itemIndex"]); // 输出:"18"
}
[.\n]+与[\s\S]+:
[.\n]中的".",会读为真的"."符号,而不是表示除\n以外的所有字符,所以[.\n]+与[\s\S]+是不一样的,匹配所有字符只能用[\s\S]+和[\s\S]*
(?=子表达式)和(?!子表达式):
分组构造 | 说明 | 模式 | 匹配 |
---|---|---|---|
(?=子表达式) | 零宽度正预测先行断言。 | \w+(?=.) | "He is. The dog ran. The sun is out." 中的 "is"、"ran" 和 "out" |
(?!子表达式) | 零宽度负预测先行断言。 | \b(?!un)\w+\b | "unsure sure unity used" 中的 "sure" 和 "used" |
(?!子表达式)举例:
string text="12345";
Regex regex=new Regex(@"(?!2)[0-9]");
var matchs=regex.Matches(text);
for(int i=0;i<matchs.Count;i++){
Debug.Log(matchs[i].Value);//分别输出:1,3,4,5
}
string text="12345";
Regex regex=new Regex(@"(?!2|4)[0-9]");
var matchs=regex.Matches(text);
for(int i=0;i<matchs.Count;i++){
Debug.Log(matchs[i].Value);//分别输出:1,3,5
}
string text="abcde";
Regex regex=new Regex(@"(?!a|c)[a-z]");
var matchs=regex.Matches(text);
for(int i=0;i<matchs.Count;i++){
Debug.Log(matchs[i].Value);//分别输出:b,d,e
}
string text="abcde";
Regex regex=new Regex(@"(?![ab]|e)[a-z]");
var matchs=regex.Matches(text);
for(int i=0;i<matchs.Count;i++){
Debug.Log(matchs[i].Value);//分别输出:c,d
}
string text="abcde";
Regex regex=new Regex(@"(?!ab)[a-z]");
var matchs=regex.Matches(text);
for(int i=0;i<matchs.Count;i++){
Debug.Log(matchs[i].Value);//分别输出:b,c,d,e
}
string text="abcde";
Regex regex=new Regex(@"(?!bc)[a-z]");
var matchs=regex.Matches(text);
for(int i=0;i<matchs.Count;i++){
Debug.Log(matchs[i].Value);//分别输出:a,c,d,e
}
string text="abcde";
Regex regex=new Regex(@"[a-z](?!ab)");
var matchs=regex.Matches(text);
for(int i=0;i<matchs.Count;i++){
Debug.Log(matchs[i].Value);//分别输出:a,b,c,d,e
}
string text="abcde";
Regex regex=new Regex(@"[a-z](?!bc)");
var matchs=regex.Matches(text);
for(int i=0;i<matchs.Count;i++){
Debug.Log(matchs[i].Value);//分别输出:b,c,d,e
}
string text="12345";
Regex regex=new Regex(@"[0-9](?!2)");//匹配数字0-9且数字后连接的不是2
var matchs=regex.Matches(text);
for(int i=0;i<matchs.Count;i++){
Debug.Log(matchs[i].Value);//分别输出:2,3,4,5
}
平衡组定义
string text0="<>";
string text1="<><";
Regex regex0=new Regex(@"(?<open><)+");
Regex regex1=new Regex(@"((?<open><)|(?<-open>>))+");
Debug.Log("text0 regex0 group open value:"+regex0.Match(text0).Groups["open"]);//输出:<
Debug.Log("text0 regex1 group open value:"+regex1.Match(text0).Groups["open"]);//输出:(空)
Debug.Log("text1 regex1 group open value:"+regex1.Match(text1).Groups["open"]);//输出:<
匹配对称括号
//匹配对称的尖括号"<...>"
string text="public class HelloE:HelloD<HelloF<IName<IGood<int>>,HelloE,HelloE>>,IName<int>,IGood<uint>{";
var regex=new Regex(@"\<(?:[^<>]|(?<open>\<)|(?<-open>\>))*(?(open)(?!))\>",RegexOptions.Compiled);
var matches=regex.Matches(text);
for(int i=0;i<matches.Count;i++){
Debug.Log(matches[i].Value);
}
//分别输出:
//<HelloF<IName<IGood<int>>,HelloE,HelloE>>
//<int>
//<uint>
//(?:子表达式):定义非捕获组,即不保存该组的内容
//[^character_group]:求反,即不在character_group中的任意单个字符匹配 。
//(?<open>\<)|(?<-open>\>):平衡组,匹配"<"加入"open"组的捕获列表,匹配">"从"open"组的捕获列表移除
//[^<>]|(?<open>\<)|(?<-open>\>):匹配非"<"和非">"的任意字符,"<"时加入"open"组的捕获列表,">"时从"open"组的捕获列表移除
//
//(?(name)yes|no):如果name(已命名或已编号的捕获组)具有匹项,则匹配 yes;否则匹配 no。
//(?!子表达式):零宽度负预测先行断言。如:"\b(?!un)\w+\b","unsure sure unity used" 中的 "sure" 和 "used"
//(?!):零宽度负预测先行断言。由于没有子表达式,试图匹配总是失败
//(?(open)(?!)):如果open组存在,则放弃匹配
//(?(open)(?!))\>:与?(open)(?!)|\>)匹配到的结果一样
string x = "Live for nothing,die for something";
string y = "Live for nothing,die for somebody";
Regex r = new Regex(@"^Live ([a-z]{3}) no([a-z]{5}),die \1 some\2$");
Debug.Log("x match count:" + r.Matches(x).Count);//1
Debug.Log("y match count:" + r.Matches(y).Count);//0
//^:必须从字符串的开头开始匹配;在多行模式中,必须从该行的开头开始
//$:匹配必须出现在字符串的末尾,或在字符串末尾的 \n 之前;在多行模式中,必须出现在该行的末尾之前,或在该行末尾的 \n 之前。
//{ n }:匹配上一个元素恰好 n 次。
//[ first - last ]:字符范围:与从 first 到 last的范围中的任意单个字符匹配。
//正则表达式会记忆“()”中匹配到的内容,作为一个“组”,
//并且可以通过索引的方式进行引用。表达式中的“\1”、“\2”,
string text="Live for nothing";
Regex regex0=new Regex(@"Live for no([a-z]{5})");
Regex regex1=new Regex(@"Live for no(?:[a-z]{5})");
if (regex0.IsMatch(text)){Debug.Log("regex0 group1 value:"+regex0.Match(text).Groups[1].Value);}//输出:thing
if (regex1.IsMatch(text)){Debug.Log("regex1 group1 value:"+regex1.Match(text).Groups[1].Value);}//输出:(空)
//(?: 子表达式 ):定义非捕获组。即不保存该组的内容