我们用match( )方法可以得到匹配到的字符串内容,但是如果想从中字符串中提取一部分内容,该怎么办呢?
这里可以使用( )括号将想提取的字符串括起来。( )实际上标记了一个子表达式的开始和结束位置,被标记的每个子表达式会依次对应每一个分组,调用group( )方法传入分组的索引即可获取提取的结果,示例如下:
代码
这里我们想把字符串中的1234567提取出来,此时可以将数字部分的正则表达式用( )括起来,然后调用了group(1)获取匹配结果。
运行结果如下:
可以看到我们成功得到了1234567。这里用的是group(1),它与group( )有所不同,后者会输出完整的匹配结果,而前者会输出第一个被( )包围的匹配结果。假如正则表达式后面还有( )包括的内容,那么可以依次用group(2)、group(3)等来获取。
通用匹配
刚才我们写的正则表达式其实比较复杂,出现空白字符我们就写\s匹配,出现数字我们就用\d匹配,这样的工作量非常大。其实完全没必要这么做,因为还有一个万能匹配可以使用,那就是.*(点星)。其中.(点)可以匹配任意字符(除换行符),*(星)代表匹配前面的字符无限次,所以它们组合在一起可以匹配任意字符。有了它,我们就不用挨个字符匹配了。
接着上面的例子,我们可以改写一下正则表达式:
这里我们将中间部分直接省略,全部用.*代替,最后加一个结尾字符串就好了,运行结果如下:
可以看到,group( )方法输出了匹配的全部字符串,也就是说我们写的正则表达式匹配到目标字符串的全部内容;span( )方法输出(0,41),这是整个字符串的长度。
因此,我们可以使用.*简化正则表达式的书写。
贪婪与非贪婪
使用上面的通用匹配.*时,可能有时候匹配到的并不是我们想要的结果。看下面的例子:
这里我们依然想获取中间的数字,所以中间依然写的是(\d+)。而数字两侧由于内容比较杂乱,所以想省略来写,都写成.*。最后,组成^He.(\d+).*Demo$,看样子并没有什么问题。我们看下运行结果:
奇怪的事情发生了,我们只得到7这个数字,这是怎么回事呢?
这里就涉及一个贪婪匹配与非贪婪匹配的问题了。在贪婪匹配下,.*会匹配尽可能多的字符。正则表达式中.*后面是\d+,也就是至少一个数字,并没有指定具体多少个数字,因此,.*就尽可能匹配多的字符,这里就把123456匹配了,给\d+留下一个可满足条件的数字7,最后得到的内容就只有数字7了。
但是这里面也存在着一些问题,我们下面一节将进行更为详细的讲解。