正则表达式用法?正则表达式在线生成器
大家好,关于正则表达式用法很多朋友都还不太明白,今天小编就来为大家分享关于正则表达式在线生成器的知识,希望对各位有所帮助!
正则表达式高级用法
上一章分享了正式表达式的入门知识,以及单字符、多字符常用的匹配方法,对于工作维护过程中已经够用,但是有时候只使用基础知识来实现就会比较麻烦,如果使用高级用法就会比较方便很多。
例如:匹配一个HTML文件中两个<B>标签中的文件。
文本内容:
从上一章内容的知识可以想到的表达式可能如下:
但是这个表达式配置的结果是 AK</B> and<B>HI,而不是我们想要的 AK和 HI。
实现很简单,就是在原有“贪婪型”元字符后面加上一个?号,如下表格
前面的元字符都是对紧挨着前面的一个字符有效,例如表达式 the{3}匹配 theee字符串,假如我们想匹配连续三个 the字符串怎么办呢,这就涉及到子表达式的概念。
把一个表达式匹配的内容做为一个单独的元素嵌入到另外一个表达式中,那这个做为独立元素的表达式就是子表达式,需要使用()括起来。这个跟数学的表达式概念很类似。
并且子表达与数学表达式还有一个类似的地方就是,正则表达式的子表达式也可以嵌套使用
假如我们再加个条件:我们想匹配连续三个 the或者连续三个 you,怎么实现?这就是正则表达式的选择操作符,也叫或操作符了
上面的问题就可以使用正则表达式(the|you){3}来表示
当一个模式的全部或者部分内容由一对括号括起来时,就对表达式进行了分组(其实就是放在()中的子表达式),并且把分组匹配到内容捕获并且临时存放在内存中。这就是捕获分组,可以在后面表达式中使用就叫后向引用,或者叫回溯引用。
默认情况下,分组是从左到右依次排序从1编号,第一个分组就是1,第二个分组就是2等等。
后向引用很简单就是一个 \或者$后面跟相应编号即可。例如 \1或者$1就表示引用第一个捕获分组。
前面讲捕获分组都是通过位置编号来访问,在perl和python、.NET等语言中还支持对捕获分组命名。这样就比较容易理解
顾名思义,与捕获分组相反,就是不会将分组匹配的内容放在内存中。主要是为了提高性能。
使用方法:在分组的开头加上?:,例如(?:the)
环视是一种非捕获分组,它根据某个模式之前或者之后的内容要求匹配其他模式。环视也称为零宽度断言。
(?(id/name)yes-pattern|no-pattern)
如果给定的 id或 name存在,将会尝试匹配 yes-pattern;否则就尝试匹配 no-pattern, no-pattern可选;
例如:email样式匹配(<)?(\w+@\w+(?:\.\w+)+)(?(1)>|$),当<存在时,则最后要匹配>;否则匹配结束符$
《学习正则表达式》
《正则表达式必知必会》
如何使用正则表达式
在Sun的Java JDK 1.40版本中,Java自带了支持正则表达式的包,本文就抛砖引玉地介绍了如何使用java.util.regex包。
可粗略估计一下,除了偶尔用Linux的外,其他Linu x用户都会遇到正则表达式。正则表达式是个极端强大工具,而且在字符串模式-匹配和字符串模式-替换方面富有弹性。在Unix世界里,正则表达式几乎没有什么限制,可肯定的是,它应用非常之广泛。
正则表达式的引擎已被许多普通的Unix工具所实现,包括grep,awk,vi和Emacs等。此外,许多使用比较广泛的脚本语言也支持正则表达式,比如Python,Tcl,JavaScript,以及最著名的Perl。
我很早以前就是个Perl方面的黑客,如果你和我一样话,你也会非常依赖你手边的这些强大的text-munging工具。近几年来,像其他程序开发者一样,我也越来越关注Java的开发。
Java作为一种开发语言,有许多值得推荐的地方,但是它一直以来没有自带对正则表达式的支持。直到最近,借助于第三方的类库,Java开始支持正则表达式,但这些第三方的类库都不一致、兼容性差,而且维护代码起来很糟糕。这个缺点,对我选择Java作为首要的开发工具来说,一直是个巨大的顾虑之处。
你可以想象,当我知道Sun的Java JDK 1.40版本包含了java.util.regex(一个完全开放、自带的正则表达式包)时,是多么的高兴!很搞笑的说,我花好些时间去挖掘这个被隐藏起来的宝石。我非常惊奇的是,Java这样的一个很大改进(自带了java.util.regex包)为什么不多公开一点呢?!
最近,Java双脚都跳进了正则表达式的世界。java.util.regex包在支持正则表达也有它的过人之处,另外Java也提供详细的相关说明文档。使得朦朦胧胧的regex神秘景象也慢慢被拨开。有一些正则表达式的构成(可能最显著的是,在于糅合了字符类库)在Perl都找不到。
在regex包中,包括了两个类,Pattern(模式类)和Matcher(匹配器类)。Pattern类是用来表达和陈述所要搜索模式的对象,Matcher类是真正影响搜索的对象。另加一个新的例外类,PatternSyntaxException,当遇到不合法的搜索模式时,会抛出例外。
即使对正则表达式很熟悉,你会发现,通过java使用正则表达式也相当简单。要说明的一点是,对那些被Perl的单行匹配所宠坏的Perl狂热爱好者来说,在使用java的regex包进行替换操作时,会比他们所以前常用的方法费事些。
本文的局限之处,它不是一篇正则表达式用法的完全教程。如果读者要对正则表达进一步了解的话,推荐阅读Jeffrey Frieldl的Mastering Regular Expressions,该书由O’Reilly出版社出版。我下面就举一些例子来教读者如何使用正则表达式,以及如何更简单地去使用它。
设计一个简单的表达式来匹配任何电话号码数字可能是比较复杂的事情,原因在于电话号码格式有很多种情况。所有必须选择一个比较有效的模式。比如:(212) 555-1212, 212-555-1212和212 555 1212,某些人会认为它们都是等价的。
首先让我们构成一个正则表达式。为简单起见,先构成一个正则表达式来识别下面格式的电话号码数字:(nnn)nnn-nnnn。
第一步,创建一个pattern对象来匹配上面的子字符串。一旦程序运行后,如果需要的话,可以让这个对象一般化。匹配上面格式的正则表达可以这样构成:(\d{3})\s\d{3}-\d{4},其中\d单字符类型用来匹配从0到9的任何数字,另外{3}重复符号,是个简便的记号,用来表示有3个连续的数字位,也等效于(\d\d\d)。\s也另外一个比较有用的单字符类型,用来匹配空格,比如Space键,tab键和换行符。
是不是很简单?但是,如果把这个正则表达式的模式用在java程序中,还要做两件事。对java的解释器来说,在反斜线字符(\)前的字符有特殊的含义。在java中,与regex有关的包,并不都能理解和识别反斜线字符(\),尽管可以试试看。但为避免这一点,即为了让反斜线字符(\)在模式对象中被完全地传递,应该用双反斜线字符(\)。此外圆括号在正则表达中两层含义,如果想让它解释为字面上意思(即圆括号),也需要在它前面用双反斜线字符(\)。也就是像下面的一样:
\\(\\d{3}\\)\\s\\d{3}-\\d{4}
现在介绍怎样在java代码中实现刚才所讲的正则表达式。要记住的事,在用正则表达式的包时,在你所定义的类前需要包含该包,也就是这样的一行:
import java.util.regex.*;
下面的一段代码实现的功能是,从一个文本文件逐行读入,并逐行搜索电话号码数字,一旦找到所匹配的,然后输出在控制台。
BufferedReader in;
Pattern pattern= Pattern.compile("\\(\\d{3}\\)\\s\\d{3}-\\d{4}");
in= new BufferedReader(new FileReader("phone"));
String s;
while((s= in.readLine())!= null)
{
Matcher matcher= pattern.matcher(s);
if(matcher.find())
{
System.out.println(matcher.group());
}
}
in.close();
对那些熟悉用Python或Javascript来实现正则表达式的人来说,这段代码很平常。在Python和Javascript这些语言中,或者其他的语言,这些正则表达式一旦明确地编译过后,你想用到哪里都可以。与Perl的单步匹配相比,看起来多多做了些工作,但这并不很费事。
find()方法,就像你所想象的,用来搜索与正则表达式相匹配的任何目标字符串,group()方法,用来返回包含了所匹配文本的字符串。应注意的是,上面的代码,仅用在每行只能含有一个匹配的电话号码数字字符串时。可以肯定的说,java的正则表达式包能用在一行含有多个匹配目标时的搜索。本文的原意在于举一些简单的例子来激起读者进一步去学习java自带的正则表达式包,所以对此就没有进行深入的探讨。
这相当漂亮吧!但是很遗憾的是,这仅是个电话号码匹配器。很明显,还有两点可以改进。如果在电话号码的开头,即区位号和本地号码之间可能会有空格。我们也可匹配这些情况,则通过在正则表达式中加入\s?来实现,其中?元字符表示在模式可能有0或1个空格符。
第二点是,在本地号码位的前三位和后四位数字间有可能是空格符,而不是连字号,更有胜者,或根本就没有分隔符,就是7位数字连在一起。对这几种情况,我们可以用(-|)?来解决。这个结构的正则表达式就是转换器,它能匹配上面所说的几种情况。在()能含有管道符|时,它能匹配是否含有空格符或连字符,而尾部的?元字符表示是否根本没有分隔符的情况。
最后,区位号也可能没有包含在圆括号内,对此可以简单地在圆括号后附上?元字符,但这不是一个很好的解决方法。因为它也包含了不配对的圆括号,比如"(555"或"555)"。相反,我们可以通过另一种转换器来强迫让电话号码是否带有有圆括号:(\(\d{3}\)|\d{3})。如果我们把上面代码中的正则表达式用这些改进后的来替换的话,上面的代码就成了一个非常有用的电话号码数字匹配器:
Pattern pattern=
Pattern.compile("(\\(\\d{3}\\)|\\d{3})\\s?\\d{3}(-|)?\\d{4}");
可以确定的是,你可以自己试着进一步改进上面的代码。
现在看看第二个例子,它是从Friedl的中改编过来的。其功能是用来检查文本文件中是否有重复的单词,这在印刷排版中会经常遇到,同样也是个语法检查器的问题。
匹配单词,像其他的一样,也可以通过好几种的正则表达式来完成。可能最直接的是\b\w+\b,其优点在于只需用少量的regex元字符。其中\w元字符用来匹配从字母a到u的任何字符。+元字符表示匹配匹配一次或多次字符,\b元字符是用来说明匹配单词的边界,它可以是空格或任何一种不同的标点符号(包括逗号,句号等)。
现在,我们怎样来检查一个给定的单词是否被重复了三次?为完成这个任务,需充分利用正则表达式中的所熟知的向后扫描。如前面提到的,圆括号在正则表达式中有几种不同的用法,一个就是能提供组合类型,组合类型用来保存所匹配的结果或部分匹配的结果(以便后面能用到),即使遇到有相同的模式。在同样的正则表达中,可能(也通常期望)不止有一个组合类型。在第n个组合类型中匹配结果可以通过向后扫描来获取到。向后扫描使得搜索重复的单词非常简单:\b(\w+)\s+\1\b。
圆括号形成了一个组合类型,在这个正则表示中它是第一组合类型(也是仅有的一个)。向后扫描\1,指的是任何被\w+所匹配的单词。我们的正则表达式因此能匹配这样的单词,它有一个或多个空格符,后面还跟有一个与此相同的单词。注意的是,尾部的定位类型(\b)必不可少,它可以防止发生错误。如果我们想匹配"Paris in the the spring",而不是匹配"Java's regex package is the theme of this article"。根据java现在的格式,则上面的正则表达式就是:Pattern pattern=Pattern.compile("\\b(\\w+)\\s+\\1\\b");
最后进一步的修改是让我们的匹配器对大小写敏感。比如,下面的情况:"The the theme of this article is the Java's regex package.",这一点在regex中能非常简单地实现,即通过使用在Pattern类中预定义的静态标志CASE_INSENSITIVE:
Pattern pattern=Pattern.compile("\\b(\\w+)\\s+\\1\\b",
Pattern.CASE_INSENSITIVE);
有关正则表达式的话题是非常丰富,而且复杂的,用Java来实现也非常广泛,则需要对regex包进行的彻底研究,我们在这里所讲的只是冰山一角。即使你对正则表达式比较陌生,使用regex包后会很快发现它强大功能和可伸缩性。如果你是个来自Perl或其他语言王国的老练的正则表达式的黑客,使用过regex包后,你将会安心地投入到java的世界,而放弃其他的工具,并把java的regex包看成是手边必备的利器。
Python正则表达式的几种匹配用法
下面列出: 1.测试正则表达式是否匹配字符串的全部或部分regex=ur""#正则表达式
if re.search(regex, subject): do_something()else: do_anotherthing() 2.测试正则表达式是否匹配整个字符串 regex=ur"/Z"#正则表达式末尾以/Z结束
if re.match(regex, subject): do_something()else: do_anotherthing() 3.创建一个匹配对象,然后通过该对象获得匹配细节(Create an object with details about how the regex matches(part of) a string) regex=ur""#正则表达式
match= re.search(regex, subject)if match:# match start: match.start()# match end(exclusive): atch.end()# matched text: match.group() do_something()else: do_anotherthing() 4.获取正则表达式所匹配的子串(Get the part of a string matched by the regex) regex=ur""#正则表达式
match= re.search(regex, subject)if match: result= match.group()else: result="" 5.获取捕获组所匹配的子串(Get the part of a string matched by a capturing group) regex=ur""#正则表达式
match= re.search(regex, subject)if match: result= match.group(1)else: result="" 6.获取有名组所匹配的子串(Get the part of a string matched by a named group) regex=ur""#正则表达式
match= re.search(regex, subject)if match:result= match.group"groupname")else:result="" 7.将字符串中所有匹配的子串放入数组中(Get an array of all regex matches in a string) result= re.findall(regex, subject) 8.遍历所有匹配的子串(Iterate over all matches in a string) for match in re.finditer(r"<(.*?)/s*.*?//1>", subject)# match start: match.start()# match end(exclusive): atch.end()# matched text: match.group() 9.通过正则表达式字符串创建一个正则表达式对象(Create an object to use the same regex for many operations) reobj= re.compile(regex) 10.用法1的正则表达式对象版本(use regex object for if/else branch whether(part of) a string can be matched) reobj= re.compile(regex)if reobj.search(subject): do_something()else: do_anotherthing() 11.用法2的正则表达式对象版本(use regex object for if/else branch whether a string can be matched entirely) reobj= re.compile(r"/Z")#正则表达式末尾以/Z结束
if reobj.match(subject): do_something()else: do_anotherthing() 12.创建一个正则表达式对象,然后通过该对象获得匹配细节(Create an object with details about how the regex object matches(part of) a string) reobj= re.compile(regex) match= reobj.search(subject)if match:# match start: match.start()# match end(exclusive): atch.end()# matched text: match.group() do_something()else: do_anotherthing() 13.用正则表达式对象获取匹配子串(Use regex object to get the part of a string matched by the regex) reobj= re.compile(regex) match= reobj.search(subject)if match: result= match.group()else: result="" 14.用正则表达式对象获取捕获组所匹配的子串(Use regex object to get the part of a string matched by a capturing group) reobj= re.compile(regex) match= reobj.search(subject)if match: result= match.group(1)else: result="" 15.用正则表达式对象获取有名组所匹配的子串(Use regex object to get the part of a string matched by a named group) reobj= re.compile(regex) match= reobj.search(subject)if match: result= match.group("groupname")else: result="" 16.用正则表达式对象获取所有匹配子串并放入数组(Use regex object to get an array of all regex matches in a string) reobj= re.compile(regex) result= reobj.findall(subject) 17.通过正则表达式对象遍历所有匹配子串(Use regex object to iterate over all matches in a string) reobj= re.compile(regex)for match in reobj.finditer(subject):# match start: match.start()# match end(exclusive): match.end()# matched text: match.group()字符串替换 1.替换所有匹配的子串#用newstring替换subject中所有与正则表达式regex匹配的子串
result= re.sub(regex, newstring, subject) 2.替换所有匹配的子串(使用正则表达式对象) reobj= re.compile(regex) result= reobj.sub(newstring, subject)字符串拆分 1.字符串拆分 result= re.split(regex, subject) 2.字符串拆分(使用正则表示式对象) reobj= re.compile(regex) result= reobj.split(subject)
好了,关于正则表达式用法和正则表达式在线生成器的问题到这里结束啦,希望可以解决您的问题哈!