1.贪婪匹配

问题:给定一个字符串表示的数字,判断该数字末尾0的个数?

  • "123000": 3个0
  • "10100": 2个0
  • "1001": 0个0

先使用"^(\d+)(0*)$"匹配这三个字符串

public class Phone{
public static void matchForZero(String s){
Pattern pattern = Pattern.compile("(\\d+)(0*)$");
Matcher matcher = pattern.matcher(s);
if (matcher.matches()){
System.out.print("第一组数:"+matcher.group(1)+"\t");
System.out.println("第二组数:"+matcher.group(2));
}
}
}
public class PhoneTest {
@Test
public void testMatchForZero(){
Phone.matchForZero("123000");
Phone.matchForZero("10100");
Phone.matchForZero("1001");
}
}


结果:0并未匹配到,group1将整个字符串完全匹配
原因:正则表达式默认使用贪婪匹配,尽可能多的向后匹配

2.非贪婪匹配

1中的解决方法:使用?实现非贪婪匹配

修改方法,再次运行

public class Phone{
public static void matchForZero(String s){
Pattern pattern = Pattern.compile("(\\d+?)(0*)$");// \d尽可能少的匹配,0尽可能多的匹配
Matcher matcher = pattern.matcher(s);
if (matcher.matches()){
System.out.print("第一组数:"+matcher.group(1)+"\t");
System.out.println("第二组数:"+matcher.group(2));
}
}
}

3.区分非贪婪匹配与个数匹配

注意:?既能表示非贪婪匹配,也能表示0个或1个,所以要注意其含义

public class Phone{
public static void matchForZero(String s){
Pattern pattern = Pattern.compile("(\\d??)(9*)$");
//第一个?表示0个或1个,可以匹配0或1个9
//第二个?表示非贪婪匹配,尽可能少的匹配,两者综合,即匹配0个
Matcher matcher = pattern.matcher(s);
if (matcher.matches()){
System.out.print("第一组数:"+matcher.group(1)+"\t");
System.out.println("第二组数:"+matcher.group(2));
}
}
}
public class PhoneTest {
@Test
public void testMatchForZero(){
Phone.matchForZero("9999");
}
}

4.代码示例

4.1贪婪匹配

ZeroCount.java

package com.testList;

import java.util.regex.Matcher;
import java.util.regex.Pattern; public class ZeroCount {
public static int zeros(String s){
Pattern pattern = Pattern.compile("^\\d+(0*)$");
Matcher matcher = pattern.matcher(s);
if(matcher.matches()){
String zeroStr = matcher.group(1);
return zeroStr.length();
}
throw new IllegalArgumentException("Not a number");
}
}

ZeroCountTest.java

package com.testList;

import org.junit.Test;

import static org.junit.Assert.*;

public class ZeroCountTest {

    @Test
public void zeros() {
assertEquals(0, ZeroCount.zeros("123456"));
assertEquals(1, ZeroCount.zeros("123450"));
assertEquals(2, ZeroCount.zeros("123400"));
assertEquals(3, ZeroCount.zeros("123000"));
assertEquals(4, ZeroCount.zeros("120000"));
assertEquals(2, ZeroCount.zeros("100100"));
}
}

4.2非贪婪匹配

package com.testList;

import java.util.regex.Matcher;
import java.util.regex.Pattern; public class ZeroCount {
public static int zeros(String s){
Pattern pattern = Pattern.compile("^\\d+?(0*)$");
Matcher matcher = pattern.matcher(s);
if(matcher.matches()){
String zeroStr = matcher.group(1);
return zeroStr.length();
}
throw new IllegalArgumentException("Not a number");
}
}

5.总结

  • 正则表达式匹配默认使用贪婪匹配
  • 使用?表示对某一规则进行非贪婪匹配
  • 注意区分?的含义 \d??

廖雪峰Java9正则表达式-2正则表达式进阶-5非贪婪匹配的更多相关文章

  1. Delphi 正则表达式语法(6): 贪婪匹配与非贪婪匹配

    Delphi 正则表达式语法(6): 贪婪匹配与非贪婪匹配 //贪婪匹配 var   reg: TPerlRegEx; begin   reg := TPerlRegEx.Create(nil);   ...

  2. 正则表达式 整理(\w \s \d 点 贪婪匹配 非贪婪匹配 * + ? {} | [] ^ $ \b 单词边界 分组、re.findall()、re.split()、re.search()、re.match()、re.compile()、re.sub())

    re.findall  匹配到正则表达式的字符,匹配到的每个字符存入一个列表,返回一个匹配到的所有字符列表 一. 匹配单个字符 import re # \w 匹配所有字母.数字.下划线 re.find ...

  3. VIM 用正则表达式,非贪婪匹配,匹配竖杠,竖线, 匹配中文,中文正则,倒数第二列, 匹配任意一个字符 :

    VIM 用正则表达式 批量替换文本,多行删除,复制,移动 在VIM中 用正则表达式 批量替换文本,多行删除,复制,移动 :n1,n2 m n3     移动n1-n2行(包括n1,n2)到n3行之下: ...

  4. 廖雪峰Java9正则表达式-2正则表达式进阶-3分组匹配

    1.使用括号可以提取字符串 不加括号匹配电话号码 匹配成功后,如何提取想要的字符串? 使用(...)可以分组:"^(\d{3,4})\-(\d{6,8})$" 2.String.m ...

  5. 廖雪峰Java9正则表达式-2正则表达式进阶-6搜索和替换

    1.使用正则表达式分割字符串: String[] string.split(String regex); "a b c".split("\\s");->[ ...

  6. 廖雪峰Java9正则表达式-1正则表达式入门-2正则表达式匹配规则

    正则表达式的匹配规则: 从左到右按规则匹配 匹配规则及示例 可以匹配 不能匹配 "abc" "abc" 不能匹配:"ab", "A ...

  7. 廖雪峰Java9正则表达式-1正则表达式入门-1正则表达式简介

    1.使用代码来判断字符串 场景: 判断字符串是否是有效的电话号码:"010-12345678", "123ABC456" 判断字符串是否是有效的电子邮箱地址:& ...

  8. vim下正则表达式的非贪婪匹配

    贪婪模式是: .* 非贪婪模式是: .\{-}

  9. python正则表达式贪婪与非贪婪模式

    之前做程序的时候看到过正则表达式的贪婪与非贪婪模式,今天用的时候就想不起来了,现在这里总结一下,以备自己以后用到注意. 1.什么是正则表达式的贪婪与非贪婪匹配 如:String str="a ...

随机推荐

  1. Nacos v0.7.0:对接CMDB,实现基于标签的服务发现能力

    Nacos近期发布了0.7.0版本,该版本支持对接第三方CMDB获取CMDB数据.使用Selector机制来配置服务的路由类型.支持单机模式使用MySQL数据库.上线Node.js客户端,并修复了一些 ...

  2. thinkphp url模式

    入口文件是应用的单一入口,对应用的所有请求都定向到应用入口文件,系统会从URL参数中解析当前请求的模块.控制器和操作: http://serverName/index.php/模块/控制器/操作 这是 ...

  3. python用类实现装饰器

    一.代码 #利用__call__方法,装饰器的执行流程:当添加装饰器语法糖时,会把语法糖的变量名加()执行,并将被装饰的函数名传入.所以当类加()执行时,执行了__init__,产生的对象就是被装饰的 ...

  4. 出现不不能引java.util.Date包的情况

    出现不不能引java.util.Date包的情况 那个时间段不能引,IDE的bug,等一会儿就好了 心得:很多时候没必要和bug死磕,因为真的不是你的问题.

  5. js基础应用-打字机,震动窗口

    js基础应用一,窗口震动 html+js代码: <!DOCTYPE html> <html> <head> <meta charset="UTF-8 ...

  6. winform程序捕获全局异常,对错误信息写入日志并弹窗

    使用场景:在winform程序中如果没对方法进行try catch操作,若方法内出错,则整个程序报错并退出,如下图 如果程序已在客户手中,若没对错误的详细信息进行拍照,我们则不知道错误原因是什么.我们 ...

  7. 面试系列16 redis的持久化

    1.RDB和AOF两种持久化机制的介绍 RDB持久化机制,对redis中的数据执行周期性的持久化 AOF机制对每条写入命令作为日志,以append-only的模式写入一个日志文件中,在redis重启的 ...

  8. mysql初次使用

  9. 关系型数据库——MySQL

    [MySQL架构图] MySQL简要架构图如下图所示,引擎层以插件方式集成了不同的存储引擎,它们共用Server层对外提供服务.   连接器:用于连接管理,进行身份认证及权限相关的管理.(登录MySQ ...

  10. 【NOI2010】能量采集

    题面 题目分析 对于第\((i,j)\)个位置,对答案的贡献为\(2*gcd(i,j)-1\). 所以有\(ans=2*\sum\limits_{i=1}^n\sum\limits_{j=1}^mgc ...