正则表达式--- Look around
在正则表达式中有一组特殊的通配符---- Look around通配符,其包含四个子类通配符:
Table 2. Four Types of Look around
|
Type
|
Regex
|
Successful if the enclosed subexpression . . .
|
Positive lookbehind Negative Lookbehind
|
(?<=......) (?<!......)
|
successful if can match to the left successful if can not match to the left
|
Positive Lookahead Negative Lookahead
|
(?=......) (?!......)
|
successful if can match to the right successful if can not match to the right
|
在一般的资料中我们经常可以看见Lookahead的介绍:
(?=pattern)
|
正向预查,在任何匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如,'Windows (?=95|98|NT|2000)' 能匹配 "Windows 2000" 中的 "Windows" ,但不能匹配 "Windows 3.1" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始。
|
(?!pattern)
|
负向预查,在任何不匹配 pattern 的字符串开始处匹配查找字符串。这是一个非获取匹配,也就是说,该匹配不需要获取供以后使用。例如'Windows (?!95|98|NT|2000)' 能匹配 "Windows 3.1" 中的 "Windows",但不能匹配 "Windows 2000" 中的 "Windows"。预查不消耗字符,也就是说,在一个匹配发生后,在最后一次匹配之后立即开始下一次匹配的搜索,而不是从包含预查的字符之后开始
|
这比较详细的介绍了Look ahead通配符,从以上的一段描述中我们可以看见Look ahead通配符的特点:
1. 该通配符是一个非获取匹配;就是正则表达式引擎在处理该类通配符时不会把匹配项存储起来,不会供以后使用。
2. 该通配符是预查操作符,不消耗字符;这个可能不是很好理解,我们还是结合实例说明吧:比如有一串字符 a1b2c3,在匹配的开始,我们可以想象有一个指针,所指的位置在a的前面,我们用\w来匹配该字符串可匹配到a,然后下一个匹配应该从1之前的位置开始;但如果我们用(?=)来匹配时,我们匹配到a,可是这时候指针还是在a的前面;也就是说,指针的位置并没有改变。这就是所谓的不消耗字符。
以上介绍的”look ahead”通配符,这两个通配符被解释为正向预查和负向预查,而”look behind”的两个通配符我一直没有找到其对应的中文翻译,但是其性质和特点和”Look ahead”非常相似,唯一的不同就是”look ahead”是预查(向右),” look behind” 是”复查?”(向左)。
我们看看以上四个通配符都在什么情况下可以匹配;
string str23 = "abc9defg";
string strRegular26 = @"[a-z]{3}";
string strRegular27 = @"[a-z]{3}(?=\d)"; //lookahead
string strRegular271 = @"(?=\d)[a-z]{3}"; //lookahead
string strRegular28 = @"(?<=\d)[a-z]{3}"; //lookbehind
string strRegular281 = @"[a-z]{3}(?<=\d)"; //lookbehind
Console.WriteLine(Regex.Matches(str23,strRegular26).Count.ToString()); // 2
Console.WriteLine(Regex.Matches(str23,strRegular26)[0].Captures[0].ToString()); // abc
Console.WriteLine(Regex.Matches(str23,strRegular26)[1].Captures[0].ToString()); // def
Console.WriteLine(Regex.Matches(str23,strRegular27).Count.ToString()); // 1
Console.WriteLine(Regex.Matches(str23,strRegular27)[0].Captures[0].ToString()); // abc
Console.WriteLine(Regex.Matches(str23,strRegular271).Count.ToString()); // 0
// Console.WriteLine(Regex.Matches(str23,strRegular271)[0].Captures[0].ToString()); // 前向预查不消耗字符,所以这个匹配永远不可能出现
Console.WriteLine(Regex.Matches(str23,strRegular28).Count.ToString());//1
Console.WriteLine(Regex.Matches(str23,strRegular28)[0].Captures[0].ToString());//def
以上是一段.net环境下c#实现的代码,每句话的后面给出了输出结果,和常规表达式@"[a-z]{3}"相比较,在表达式变为: @"[a-z]{3}(?=\d)"时不匹配原有的”def”因为在向右看时,”def”后面不是数字。在表达式变为@"(?<=\d)[a-z]{3}"后不匹配原有的”abc”,因为在向左看时,”abc”前面没有数字。
让我们来看一段示例:
通过常用通配符和这四个通配符(不一定全用到)的结合,让我们试着将一串夹在字符串中的数字用千分号分隔开:
如:
The value is 123456789 dollars.
通过正则表达式变为:
The value is 123,456,789 dollars.
或者将:
The result is 123456789
通过正则表达式变为:
The result is 123,456,789
让我们分析这个问题:
首先分析我们应该如何分割123456789
毫无疑问,我们应该从右边不是数字的字符或者位置开始,每隔3个数字且该位置之前还是数字(如 4前面和7前面是应该找到了,而1前面不是应该匹配的。)
那么让我们逐步完善匹配正则表达式:
首先是匹配模式:在.net中应该用RegexOptions.RightToLeft.
是一点首先明确,然后是左边不是数字,如果用的是 (?=[^0-9]+) 这已经很接近了,可是一个问题是不能匹配数字后什么都没有的东西了(因为用了一个+)所以我们可以完善为"(?=(\D|$))"
且右边有3个一组的数字一组或者多组:"(?=(\d{3})+(\D|$))",
而且左边至少有一位数字 :"\d(?=(\d{3})+(\D|$))"这样我们通过这个正则表达式去匹配,我们就可以找到123456789中的3和6了,这离123,456,789已经非常接近了。
我们需要将3替换为3,而6替换为6,所以我们需要将3和6捕获到:"(\d)(?=(\d{3})+(\D|$))"
这时候我们可以采用Timmy的方式用 Regex.Replace(strTest,strPattern,new atchEvaluator ReplaceNumber));
或者我们在正则表达式的替换中我们可以用$1来获取我们的第一组捕获,这样我们就可以得到一种解决方案:
string str37 = "123456789";
string strRegular47 = @"(\d)(?=(\d{3})+(\D|$))";
Console.WriteLine(Regex.Replace(str37,strRegular47,"$1,",RegexOptions.RightToLeft ));
这是一种替换"3" -> "3," ; "6" -> "6,"的一种方式。这里我们就到一个Positive Lookahead,那么其实我们的实际操作就是希望在"3"和"6"的位置后插入一个",",我们可不可以只找出这个位置,然后替换为","呢?
我想我们通过(?<=......) 和(?<!......) 是可以达到只找到这个位置的目的的:)
这里我也将表达式给出:(?<=\d+)(?=(\d{3})+(\D|$))
这样以上的表达式就只会匹配一个位置,而不对应任何字符,用
string str37 = "123456789";
string strRegular47 = @"(?<=\d+)(?=(\d{3})+(\D|$))";
Console.WriteLine(Regex.Replace(str37,strRegular47,",",RegexOptions.RightToLeft ));
这样就可以不用捕获,也能完成插入","了。
我们还可以对这个问题进行扩展,比如123456789.123456如果采用以上的方式处理就会获得 123,456,789.123,456
这显然不太合适的,我们应该获得的是"123,456,789.123456",即小数点后不加以格式化。那么这个正则表达式又应该怎么写呢?
这还是需要大家多多考虑。
要熟悉正则,就是要多多练习,尤其是我们进行搜索的时候,还是很有用处的。:)
现对关于正则表达式中look around的总结如下:
1. 是非捕获匹配,不消耗字符。
2. 有look ahead (向右)和look behind(向后)两种。其下又分正匹配和负匹配两种,共4种。
3. 属于特殊通配符,比较不容易通过其他通配符替代。
4.合理运用可以大大提到字符处理效率。
分享到:
相关推荐
本资源“源码(精通正则表达式&实战正则表达式)”专注于JavaScript环境下的正则表达式学习,通过一系列视频教程和配套源码,帮助开发者提升对正则表达式的理解和应用能力。 首先,"精通正则表达式五部视频"可能涵盖...
正则表达式的能力远超简单的通配符,能匹配更为复杂的文本模式。例如,通配符在文件搜索中只能粗略地匹配文件名,而正则表达式能够匹配具体的文本内容和格式。 正则表达式由普通字符(例如字母和数字)以及特殊字符...
4. **高级特性**:如lookaround(前瞻后顾)、条件表达式、嵌套结构等,这些都是正则表达式进阶使用的必备知识,能实现更精细的匹配控制。 5. **正则表达式引擎的差异**:书中讨论了不同的正则表达式引擎(如Perl、...
正则表达式是一种强大的文本处理工具,用于在字符串中匹配、查找、替换或提取特定模式。它是编程语言中不可或缺的一部分,适用于数据验证、文本搜索和替换等任务。本教程是专为初学者设计的,旨在提供一个简单易懂的...
书中还深入讨论了正则表达式的高级特性,如后行断言(lookaround)、条件表达式、嵌套重复和递归,这些都是处理复杂文本模式的关键工具。此外,Friedl还探讨了在实际项目中如何优化正则表达式,避免性能问题,并提供...
正则表达式(Regular Expression,简称regex)是用于匹配字符串的一种模式,广泛应用于文本处理、数据验证、搜索和替换等场景。在编程语言中,如Java,正则表达式是通过特定的API来使用的,例如Java的`java.util....
正则表达式(Regular Expression,简称regex)是一种强大的文本处理工具,它用于匹配、查找、替换、分析等涉及字符串操作的复杂任务。正则表达式编辑器是专门用来创建、测试和调试正则表达式的软件工具,对于程序员...
《.NET正则表达式(网页版)》是针对ASP.NET和C#开发者的一个资源,旨在帮助他们理解和掌握正则表达式这一强大的文本处理工具。正则表达式(Regular Expression)在编程领域中广泛用于数据验证、搜索与替换等场景,...
正则表达式是一种强大的文本处理工具,用于匹配、查找、替换和分析字符串模式。它在编程语言、文本编辑器和各种脚本环境中广泛使用。在这个“正则表达式系统教程”中,我们可以深入理解正则表达式的概念和用法。 1....
实战正则表达式第2讲可能涵盖了更复杂的正则表达式构造,如环视(lookaround)——前瞻断言(lookahead)和后顾断言(lookbehind),以及更高级的用法,如使用条件语句和非捕获组等。这些高级特性能够使正则表达式...
正则表达式(Regular Expression,简称regex)是用于匹配字符串的一种模式,广泛应用于文本处理、数据验证、搜索和替换等场景。它通过一系列特殊字符和语法构造出规则,用来匹配符合特定模式的字符串。在本教程中,...
本书的第三版(3rd.Edition)涵盖了正则表达式的最新发展,包括Unicode支持、预查(lookaround)以及更多的高级特性。作者 Jeffrey E.F. Friedl 用通俗易懂的语言和丰富的实例,引导读者逐步掌握正则表达式的精髓。 ...
正则表达式是一种强大的文本处理工具,用于在字符串中进行模式匹配和搜索替换。它在编程语言中广泛应用,包括C#。这篇文档“深入浅出之正则表达式”将引领我们逐步理解这一复杂的概念。 1. **正则表达式基础** - ...
正则表达式(Regular Expression,简称regex)是一种强大的文本处理工具,用于匹配、查找、替换等操作。在编程和数据分析领域,正则表达式扮演着不可或缺的角色。`regextester`是一款专门针对正则表达式的测试工具,...
此外,正则表达式还涉及到一些高级技巧,如lookaround(前瞻后顾)和条件表达式,它们可以实现更复杂的匹配逻辑。例如,(?=...)可以匹配紧随其后的模式,而(?!...)则匹配后面不跟指定模式的位置。 《正则表达式自学...
6. **高级用法**:包括零宽度断言(如前瞻断言和后顾断言)、条件表达式、环视(lookaround)等复杂技巧,这些高级特性使得正则表达式可以进行更精确的匹配。 7. **实战应用**:书中可能会提供大量的实例,如邮箱...
正则表达式是一种强大的文本处理工具,用于匹配、查找、替换和分析字符串。它通过一套特定的模式来描述字符组合,广泛应用于编程语言、文本编辑器、搜索引擎等场景。正则表达式的学习不仅可以提高文本处理的效率,还...
- C#中的正则表达式支持`lookaround`,如`(?)`和`(?<!...)`,以及`平衡组`(平衡括号)。 6. **学习资源**: - 提供的文档"javascript正则表达式.doc"和"一些正则表达式的含义.doc"可以深入理解正则表达式的具体...
Java中的正则表达式是处理字符串的强大工具,它允许我们以一种简洁的方式匹配、查找、替换和解析文本。正则表达式(Regular Expression)在Java编程语言中通过`java.util.regex`包提供支持。这个包包含三个核心类:`...
正则表达式是一种强大的文本处理工具,用于匹配、查找、替换和分析字符串模式。它在IT行业中被广泛应用,尤其是在编程语言、数据验证、文本编辑器和搜索引擎等领域。本教程是针对正则表达式的一个系统性指导,旨在...