正则的一些应用

基础准备

史上最全正则表达式总结_Mr_Gu的博客-CSDN博客

正则提取代码示例:

public static String regexpExtract(String str, String regex) {
        if (str == null || regex == null) {
            return "";
        }
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        if (matcher.find()) {
            int n = matcher.groupCount();
            for (int i = 1; i <= n; i++) {
                String val = matcher.group(i);
                if(val!=null){
                  return matcher.group(i);
              }
            }
        }
        return "";
    }

零宽断言

零宽断言,大多地方这样定义它,用于查找在某些内容(但并不包括这些内容)之前或之后的东西。

我的理解是在一个限定位置的字符串之前或之后进行匹配查找。

所以零宽断言,执行过程分两种情况,如果是正向断言,应该是这样的,第一步,判断判断断言是否为真(即是否满足一定条件)第二步,如果满足条件,则进行下一步查找匹配。如果是反向断言,第一步还是按照正则表达式顺序去匹配。第二步,遇到反向代言,判断是否满足反之代言。

可以用领宽断言实现逻辑and

零宽断言有四类,它不匹配字符,只匹配一个位置,这和\b很像。用于断言后面的内容。

零宽度正预测先行断言
(?=exp)也叫零宽度正预测先行断言,它断言自身出现的位置的后面能匹配表达式exp。比如\b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找I'm singing while you're dancing.时,它会匹配sing和danc。


零宽度正回顾后发断言
(?<=exp)也叫零宽度正回顾后发断言,它断言自身出现的位置的前面能匹配表达式exp。比如(?<=\bre)\w+\b会匹配以re开头的单词的后半部分(除了re以外的部分),例如在查找reading a book时,它匹配ading。

零宽度负预测先行断言
零宽度负预测先行断言(?!exp),断言此位置的后面不能匹配表达式exp。例如:\d{3}(?!\d)匹配三位数字,而且这三位数字的后面不能是数字;\b((?!abc)\w)+\b匹配不包含连续字符串abc的单词。

零宽度负回顾后发断言
同理,我们可以用(?<!exp),零宽度负回顾后发断言来断言此位置的前面不能匹配表达式exp:(?<![a-z])\d{7}匹配前面不是小写字母的七位数字。

零宽断言(?=exp)匹配exp前面的位置
(?<=exp)匹配exp后面的位置
(?!exp)匹配后面跟的不是exp的位置
(?<!exp)匹配前面不是exp的位置

示例:

前后同时使用

str="教师14(0014)"

regex="(?<=\\()(.+?)(?=\\))";

不讲先后顺序匹配

应用场景就是,已知字符串中包含x,y,z三个词语,但是不确定顺序,需要同时将这三个词匹配出来。一般使用 (?=.*x)(?=.*y)(?=.*z) 这种断言。

1.不讲顺序提取出url的请求值

不讲先后顺序匹配字符串:此处中serialid和cityid的匹配不讲先后顺序

regex=regex : ".*api\\.app\\.yiche\\.com/webapi/api\\.ashx.*(?=.*?serialid=)(?=.*?cityid=).*"

2.不考虑先后顺序,提取出包含组合关键词所在的句子

分析:先判定整句,前后都不是整句断句标识的就判断是整句,用[^.^。^!^!]* 

捕捉的关键词不讲顺序,用 (?=.*x)(?=.*y)模式匹配。

不同之处是断言内部关键词前,不能是整句标识,这样才能得到匹配结果。

String keywords="(?=[^.^。^!^!]*北京冬奥会)(?=[^.^。^!^!]*西班牙)";
String reg="([^.^。^!^!]*"+keywords+"[^.^。^!^!]*)";

来源

js 正则 表达式 多关键词 忽略顺序 顺序无关 模糊搜索 查询 匹配通用方法_yanxiaomu的博客-CSDN博客如题,有需求需实现基于js的多关键词顺序无关模糊搜索,多关键词以空格区分比如 男 皮鞋 亮皮 需要能够匹配以下组合男款韩版皮鞋春季亮皮韩版皮鞋男款春季亮皮男款亮皮韩版皮鞋春季男款韩版春季亮皮皮鞋…(总之与顺序无关)代码也简单一个函数搞定function createMutilWordQueryReg (query) { let regStr = query; if (query.indexOf(' ') !== -1) { // new RegExp('^https://blog.csdn.net/yanxiaomu/article/details/113813550?ops_request_misc=&request_id=&biz_id=102&utm_term=%E5%A4%9A%E4%B8%AA%E8%AF%8D%20%E4%B8%8D%E8%AE%B2%E9%A1%BA%E5%BA%8F%20%E6%AD%A3%E5%88%99%E6%8F%90%E5%8F%96&utm_medium=distribute.pc_search_result.none-task-blog-2~all~sobaiduweb~default-0-113813550.first_rank_v2_pc_rank_v29&spm=1018.2226.3001.4187

不捕捉模式

也可以将零宽断言理解为不捕捉模式的应用
如何关闭圆括号的捕获能力?而只是用它来做分组,方法是在左括号的后边加上:?,这里第一个圆括弧只是用来分组,而不会占用捕获变量,所以$1的内容只能是steak或者burger,而永远不可能是bronto。
while(<>){
    if(/(?:bronto)(steak|burger)/){
        print "Fred wants a $1\n" ;
    }

}

遇见功能,"?=",意识说目标串中肯定存在什么
str="ab4";
reg=/ab(?=\d)


"?!",意思说目标串中不应该存在什么
str="ab1";
reg=/ab(?!\d)

性能提高

来源:

正则表达式性能提高_csdncjh的博客-CSDN博客这里说的正则表达式优化,主要是针对目前常用的NFA模式正则表达式,详细可以参考:正则表达式匹配解析过程探讨分析(正则表达式匹配原理)。从上面例子,我们可以推断出,影响NFA类正则表达式(常见语言:GNU Emacs,Java,ergp,less,more,.NET语言, PCRE library,Perl,PHP,Python,Ruby,sed,vi )其实主要是它的“回溯”,减少“回溯”https://blog.csdn.net/csdncjh/article/details/51191616?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522163843012316780357228315%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=163843012316780357228315&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~blog~first_rank_v2~rank_v29-1-51191616.pc_v2_rank_blog_default&utm_term=%E6%AD%A3%E5%88%99&spm=1018.2226.3001.4450

问号的四种用法

正则表达式-问号的四种用法 - 翰墨小生 - 博客园

1.原文符号

2.有无量词

3..非贪婪匹配

贪婪匹配
在满足匹配时,匹配尽可能长的字符串,默认情况下,采用贪婪匹配

非贪婪匹配
在满足匹配时,匹配尽可能短的字符串,使用?来表示非贪婪匹配

几个非场景的非贪婪pattern

4.不捕捉模式 

如何关闭圆括号的捕获能力?而只是用它来做分组,方法是在左括号的后边加上:?

替换功能

//希望将字符串中的数字包裹进[]中
String str="dasfdab123adfbad124";
String reg="";
String str2 = str.replaceAll("\\d+", "[$0]");
System.out.println(str2);

结果是:dasfdab[123]adfbad[124]

多组正则合并

示例:希望从以下四种url中提出出用户id

https://weibo.com/7362321881
https://weibo.com/u/7362321881
https://weibo.com/n/我泪水是无底深海对你的爱已无言
https://weibo.com/polishembassy

 如果用断言的话,相互之间的提取正则会影响,需要合并多组正则,用|串起来,才能确保满足所有条件

public class RegTest {
    public static void main(String[] args) {
        String reg="weibo.com/n/([^/]+)|weibo.com/(\\d+)|weibo.com/u/(\\d+)|weibo.com(?!/n/)(?!/u/)/(\\w+)";
//         str="https://weibo.com/polishembassy";
//         str="https://weibo.com/7362321881";
//         str="https://weibo.com/u/7362321881";
        str="https://weibo.com/n/我泪水是无底深海对你的爱已无言";
        String result = StrUtils.regexpExtract(str, reg);
        System.out.println("result = " + result);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值