正则表达式优化

正则表达式的优化  在Jeffrey E. F. Friedl 的<<精通正则表达式>>中提到了几种技巧。今天着重说一种比较实用的。

 

比较简单的:

        在类似 .* 或者 [\s\S]*中匹配的时候,量词* 默认是贪婪的,启用最大匹配模式, 会匹配到尽量多的字符串,如果我们的需求是匹配<b>text</b>中的text,这样就不适用了。具体来说,我们假设这个正则表达式是: <b>.*</b>但是如果目标字符串很长 <b>text</b>ssssssssssss....(此处省略100000个s) 这样就很悲催,.* 会匹配<b>后面所有的字符串,也就是 100000+ 的字符串,然后一个一个回朔,回朔100000多次之后才正确匹配</b>

       很显然这种量词最大匹配的模式效率很差,当然字符串小的话无所谓,可以用?号开启最小匹配模式。优化后的表达式是 <b>.*?</b> , 让*号默认从小的开始,就是匹配一个字符之后,将后面的跟</b>进行对比。这样4次比较就哦了。 

 

稍微复杂点的:

在书中,提炼出了一种匹配的通用模式

normal*(specail normal*) 咋一看不知道什么意思,简单的说 就是让normail尽量多的匹配正常的文本,然后摘出需要特殊处理的字符,增加对非常规字符的处理。我们举一个例子来说明这种问题。

还是匹配<b>text</b> 一般的,严格一点,我们使用 <b>(?!</?b>.)*</b>来匹配只要中间不出现<b>或者</b>都认为结束了,但是这是一个串匹配的过程,效率还不是最优的。

用通用模式来实现可以写成:

<b>                       #匹配开头的<b>

    (?>[^<]*)            #匹配任意数量的normal 

       (?>                 #固化分组

           (?!</?b>)    #锚定不是需要标签的字符

           <                  #特殊字符

           [^<]*              #匹配任意数量的normal

        )*                      #

</b>                          #匹配尾部的</b>

这种模式的核心思想视永不回朔,永远向前匹配,技巧性很强,你得先分析出什么字符可以作为specail的,在本例中,使用了< 字符,应为</b>的第一个字符就是 < , 把中间的内容都跟<比, 中间内容可能含有<a><html>诸如此类的内容, 要把<a>跟</b>区分开来,使用了锚定,相当于在有< 的时候做下判断,是单字符比较,速度较快。

在 Java 中使用正则表达式可以显著优化字符串匹配和筛选的逻辑,尤其适用于复杂的文本处理任务。相比传统的字符串遍历方式(如 `charAt`、`substring` 等),正则表达式能更高效地表达和处理复杂的模式匹配需求[^1]。通过 `java.util.regex` 包中的 `Pattern` 和 `Matcher` 类,可以实现更简洁、可读性更强的代码。 ### 使用正则表达式优化密码子串查找 以下是一个基于正则表达式优化的密码子串查找实现。该实现满足以下条件: - 子串长度在 6 到 12 之间。 - 包含至少一个大写字母。 - 包含至少一个小写字母或数字。 - 包含至少一个特殊字符(如 `!@#$%^&*`)。 - 不包含用户名。 ```java import java.util.*; import java.util.regex.*; public class PasswordFinderRegex { public static String findValidPassword(String pwdPool, String userName) { List<String> validPasswords = new ArrayList<>(); String regex = "(?=.*[A-Z])(?=.*[a-z0-9])(?=.*[!@#$%^&*])[A-Za-z0-9!@#$%^&*]{6,12}"; Pattern pattern = Pattern.compile(regex); Matcher matcher = pattern.matcher(pwdPool); while (matcher.find()) { String candidate = matcher.group(); if (!candidate.contains(userName)) { validPasswords.add(candidate); } } if (!validPasswords.isEmpty()) { Collections.sort(validPasswords); return validPasswords.get(0); } else { return null; } } public static void main(String[] args) { String pwdPool = "aA1!abcXYZ789@def"; String userName = "abc"; String result = findValidPassword(pwdPool, userName); System.out.println(result != null ? result : -1); } } ``` ### 说明与优势 - **正则表达式匹配**:使用 `Pattern` 和 `Matcher` 可以高效地匹配符合条件的子串,避免了手动遍历字符数组的复杂性[^2]。 - **逻辑清晰**:正则表达式将多个条件封装在一个表达式中,提升了代码的可读性和维护性。 - **性能优化**:正则表达式引擎经过优化,通常比手动实现的字符遍历更高效,尤其在大规模文本处理中表现更优。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值