廖雪峰Java9正則表達式-2正則表達式進階-5非貪婪匹配


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??


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM