首页 > 其他分享 >正则表达式的贪婪和非贪婪模式

正则表达式的贪婪和非贪婪模式

时间:2023-06-19 11:06:44浏览次数:36  
标签:匹配 正则表达式 模式 content 贪婪 println hello


最近在写程序时,碰到一个场景,需要找到一个字符串中指定的一个片段,而不是所有片段,这就涉及到正则表达式中贪婪和非贪婪两种模式。

字面意思上,正则表达式一般趋向于最大长度匹配,就是贪婪模式。匹配到结果就好,就少的匹配字符,就是非贪婪模式。

直接上个例子,

String str="abcaxc";
Patter p="ab.*c";

如果是贪婪模式,上面使用模式p匹配字符串str,结果就是匹配到:abcaxc,匹配到了所有的字符串。

如果是非贪婪模式,上面使用模式p匹配字符串str,结果就是匹配到:abc,只匹配到了部分的字符串。

编程中怎样区分这两种模式?

默认情况下,正则用的都是贪婪模式,如果要使用非贪婪模式,需要在量词后面直接加上一个问号"?",量词包括如下,

(1) {m,n}:m到n个。

(2) *:任意多个。

(3) +:一个到多个。

(4) ?:0或一个。

再上个程序,用贪婪和非贪婪模式找到content中的内容,

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class RegularTest {
  public static void main(String[] arg) {
    String text = "(content:\"hello root\";hello:\"word\";)";
    String rule1 = "content:\".+\"";  // 贪婪模式
    String rule2 = "content:\".+?\""; // 非贪婪模式


    System.out.println("文本:" + text);
    System.out.println("贪婪模式:" + rule1);
    Pattern p1 = Pattern.compile(rule1);
    Matcher m1 = p1.matcher(text);
    while (m1.find()) {
      System.out.println("匹配结果:" + m1.group(0));
    }


    System.out.println("非贪婪模式:" + rule2);
    Pattern p2 = Pattern.compile(rule2);
    Matcher m2 = p2.matcher(text);
    while (m2.find()) {
      System.out.println("匹配结果:" + m2.group(0));
    }
  }
}

如果是贪婪模式,返回两个字符串,而非贪婪模式,则只返回第一个,

文本:(content:"hello root";hello:"word";)
贪婪模式:content:".+"
匹配结果:content:"hello root";hello:"word"
非贪婪模式:content:".+?"
匹配结果:content:"hello root"

针对不同场景,我们就可以选择合适的模式。


标签:匹配,正则表达式,模式,content,贪婪,println,hello
From: https://blog.51cto.com/u_13950417/6511631

相关文章

  • 代理模式实现隔离层架构,自由切换三方网络请求框架
    使用代理模式实现隔离层架构,目的是为了当出现一个新的网络框架的时候,可以在业务层无感的情况下自由切换网络库,实现热插拔,对业务层几乎没有影响。1架构图以用户租房为例,租户相当于APP的业务层;一个用户会对比多套房子,所以会有多个房东,最终提供房源的是房东,所以房东就类似最终实现网......
  • 20230426 22. 桥接模式 - 手机软件
    介绍对象的继承关系是在编译时就定义好了,所以无法在运行时改变从父类继承的实现。子类的实现与它的父类有非常紧密的依赖关系,以至于父类实现中的任何变化必然会导致子类发生变化。当你需要复用子类时,如果继承下来的实现不适合解决新的问题,则父类必须重写或被其他更适合的类替换。......
  • 20230426 21. 单例模式
    介绍单例模式(Singleton),保证一个类仅有一个实例,并提供一个访问它的全局访问点。通常我们可以让一个全局变量使得一个对象被访问,但它不能防止你实例化多个对象。一个最好的办法就是,让类自身负责保存它的唯一实例。这个类可以保证没有其他实例可以被创建,并且它可以提供一个访问该......
  • Oceanbase中Rowkey String的几种使用模式
    1.Rowkey深拷贝 直接进行Rowkey赋值的时候数据是浅拷贝的。为了深拷贝数据,往往提供一个MemBuffer或者StringBuffer,将源rowkey的数据memcpy到缓冲区(buffer),然后再将目的rowkey的指针指向buffer。2.Rowkey计算Hash  在老版本OB中,rowkey的hash值是通过murmurhash函数计算,输入是......
  • 20230421 10. 模板方法模式 - 试卷答题
    既然用了继承,并且肯定这个继承有意义,就应该要成为子类的模板,所有重复的代码都应该要上升到父类去,而不是让每个子类都去重复当我们要完成在某一细节层次一致的一个过程或一系列步骤,但其个别步骤在更详细的层次上的实现可能不同时,我们通常考虑用模板方法模式来处理模板方法(Templa......
  • 20230423 15. 抽象工厂模式 - 数据库
    介绍工厂方法模式是定义一个用于创建对象的接口,让子类决定实例化哪一个类。抽象工厂模式(AbstractFactory),提供一个创建一系列相关或相互依赖对象的接口,而无须指定它们具体的类。AbstractProductA和AbstractProductB是两个抽象产品,之所以为抽象,是因为它们都有可能有两种不同......
  • 20230421 14. 观察者模式 - 摸鱼通知
    观察者模式又叫作发布-订阅(Publish/Subscribe)模式观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。Subject类,可翻译为主题或抽象通知者,一般用一个抽象类或者一个......
  • 20230421 13. 建造者模式 - 画小人
    '建造者模式(Builder)',又叫生成器模式建造者模式(Builder),将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。如果我们用了建造者模式,那么用户就只需指定需要建造的类型就可以得到它们,而具体建造的过程和细节就不需要知道了。Builder是为创建一个Pro......
  • 20230426 18. 备忘录模式 - 游戏人物
    介绍备忘录(Memento):在不破坏封装性的前提下,捕获一个对象的内部状态,并在该对象之外保存这个状态。这样以后就可将该对象恢复到原先保存的状态。Originator(发起人):负责创建一个备忘录Memento,用以记录当前时刻它的内部状态,并可使用备忘录恢复内部状态。Originator可根据需要决定M......
  • 20230426 17. 适配器模式 - NBA外籍中锋
    介绍适配器模式(Adapter),将一个类的接口转换成客户希望的另外一个接口。Adapter模式使得原本由于接口不兼容而不能一起工作的那些类可以一起工作。适配器模式主要解决的问题:简单地说,就是需要的东西就在面前,但却不能使用,而短时间又无法改造它,于是我们就想办法适配它系统的数据和......