()回溯与非回溯
使用(?>…)方式进行非回溯声明由于正则表达式引擎的贪婪特性导致它在某些情况下将进行回溯以获得匹配请看下面的示例
Code
string x = Live for nothingdie for something;
Regex r = new Regex(@*thing);
if (rIsMatch(x))
{
ConsoleWriteLine(match: + rMatch(x)Value);//输出Live for nothing
}
Regex r = new Regex(@(?>*)thing);
if (rIsMatch(x))//不匹配
{
ConsoleWriteLine(match: + rMatch(x)Value);
}
//在r中*由于其贪婪特性将一直匹配到字符串的最后随后匹配thing但在匹配时失败此时引擎将回溯并在thing处匹配成功
在r中由于强制非回溯所以整个表达式匹配失败
()正向预搜索反向预搜索
正向预搜索声明格式正声明 (?=…)负声明 (?!) 声明本身不作为最终匹配结果的一部分请看下面的示例
Code
string x = used free;
Regex r = new Regex(@\d{}(?= used));
if (rMatches(x)Count==)
{
ConsoleWriteLine(r match: + rMatch(x)Value);//输出
}
Regex r = new Regex(@\d{}(?! used));
if (rMatches(x)Count==)
{
ConsoleWriteLine(r match: + rMatch(x)Value); //输出
}
//r中的正声明表示必须保证在四位数字的后面必须紧跟着 usedr中的负声明表示四位数字之后不能跟有 used
反向预搜索声明格式正声明(?<=)负声明(?
string x = used: free:;
Regex r = new Regex(@(?<=used:)\d{});
if (rMatches(x)Count==)
{
ConsoleWriteLine(r match: + rMatch(x)Value);//输出
}
Regex r = new Regex(@(?
if (rMatches(x)Count==)
{
ConsoleWriteLine(r match: + rMatch(x)Value);//输出
}
//r中的反向正声明表示在位数字之前必须紧跟着used:r中的反向负声明表示在位数字之前必须紧跟着除used:之外的字符串
()十六进制字符范围
正则表达式中可以使用 \xXX 和 \uXXXX 表示一个字符(X 表示一个十六进制数)形式字符范围
\xXX 编号在 到 范围的字符比如空格可以使用 \x 表示
\uXXXX 任何字符可以使用 \u 再加上其编号的位十六进制数表示比如汉字可以使用[\ue\ufa]表示
()对[]的比较完备的匹配
下面是一个比较综合的示例对于匹配[]需要特殊考虑的地方包括
*合法合法合法合法
*空字符串不合法仅小数点不合法大于不合法
*数值是可带后缀的如f表示该值为一个float类型(未考虑)
Code
Regex r = new Regex(@^\+?*(?:(\*)?|(\d{}(?=\\d)|\d{}(?=($|\$)))(\\d*)?)$);
string x = ;
while (true)
{
x = ConsoleReadLine();
if (x != exit)
{
if (rIsMatch(x))
{
ConsoleWriteLine(x + succeed!);
}
else
{
ConsoleWriteLine(x + failed!);
}
}
else
{
break;
}
}
()精确匹配有时候是困难的
有些需求要做到精确匹配比较困难例如日期UrlEmail地址等其中一些你甚至需要研究一些专门的文档写出精确完备的表达式对于这种情况只能退而求其次保证比较精确的匹配例如对于日期可以基于应用系统的实际情况考虑一段较短的时间或者对于像Email的匹配可以只考虑最常见的形式