Java正则表达式验证是否包含某字符串|拿来即用的示例代码及解析

文章目录CloseOpen

    • 先搞懂:Java正则验证“包含”的核心逻辑
    • 直接用:3种常见场景的示例代码+避坑技巧
      • 场景1:精确匹配固定字符串
      • 场景2:忽略大小写/空格的模糊匹配
        • 忽略大小写:用Pattern.CASE_INSENSITIVE参数
        • 忽略空格:用\s匹配任意空格
      • 场景3:避免“部分匹配”的边界处理
    • 最后:把常用逻辑封装成工具类,省时间
      • find()和matches()的核心区别是什么?
      • Java正则里哪些特殊字符需要转义?
      • 如何忽略大小写验证字符串包含某内容?
      • 怎么避免正则匹配到“部分单词”(比如想匹配“apple”却匹配到“apples”)?
      • 封装的RegexUtils工具类可以直接用吗?需要注意什么?

    先搞懂:Java正则验证“包含”的核心逻辑

    要解决“包含”问题,首先得明确Java正则里的两个核心方法:find()matches()——很多人一开始会搞混,我也不例外。

    先问你个问题:如果字符串是“aabcf”,你要检查里面有没有“abc”,用哪个方法?答案是find(),因为matches()检查整个字符串是否完全符合正则,而find()检查字符串里有没有某部分符合正则。比如:

String str = "aabcf";

// 验证是否包含"abc"

boolean contains = Pattern.compile("abc").matcher(str).find(); // true

// 验证是否完全等于"abc"

boolean fullMatch = Pattern.compile("abc").matcher(str).matches(); // false

我之前帮运营同学做敏感词过滤时,就犯过用matches()的错:明明用户输入里有“赌博”两个字,结果matches()返回false——后来才反应过来,我要的是“包含”,不是“完全等于”。

再来说转义字符——这是正则里最容易踩的坑。比如你要找包含“.”的字符串(比如“www.baidu.com”里的“www.”),正则得写“\.”,而不是“.”。因为“.”在正则里代表“任意字符”,如果不转义,“www.”会匹配“wwwXcom”(X是任意字符),而不是你要的“www.”本身。

举个我经历过的例子:去年帮客服做订单号校验工具,要检查订单号里有没有“Java+”(比如“Java+12345”),一开始正则写的是“Java+”,结果把“Javaaaaa12345”也匹配上了——因为“+”在正则里代表“前面的字符出现1次或多次”,所以“Java+”会匹配“Java”“Javaa”“Javaaa”等。后来改成“Java\+”才对——记住,正则里的特殊字符(. + ? | ( ) [ ] { } ^ $ )都要转义,Java字符串里得写两个反斜杠,比如“\+”“\.”。

直接用:3种常见场景的示例代码+避坑技巧

搞懂核心逻辑后,接下来是日常开发中最常用的3种场景——每个场景都给你能直接复制粘贴的代码,还有我踩过的坑,帮你少走弯路。

场景1:精确匹配固定字符串

最基础的场景:检查字符串里有没有某个固定且无特殊字符的字符串,比如“error”“success”“timeout”。

示例代码:

// 要检查的字符串

String log = "请求失败:error_code=500";

// 要匹配的固定关键词

String regex = "error";

// 编译正则(Pattern是线程安全的,可缓存)

Pattern pattern = Pattern.compile(regex);

// 匹配并判断是否包含

boolean contains = pattern.matcher(log).find();

System.out.println("日志含error吗?" + contains); // true

避坑技巧

如果关键词里有特殊字符,一定要转义。比如要找包含“www.”的字符串,正则是“www\.”;要找包含“”的字符串,正则是“\”——我之前帮运营同学做链接过滤时,就因为没转义“.”,把“wwwXcom”也过滤了,后来改成“www\.”才对。

场景2:忽略大小写/空格的模糊匹配

有时候你不需要精确匹配大小写(比如“Timeout”“timeout”),或者不管关键词中间的空格(比如“user name”“username”),这时候可以用正则的“模糊匹配”技巧。

忽略大小写:用Pattern.CASE_INSENSITIVE参数

Java里可以通过Pattern.CASE_INSENSITIVE常量实现忽略大小写——这个参数对ASCII字符(比如A-Z、a-z)有效,比如:

String str = "请求超时:Timeout";

String regex = "timeout";

// 编译正则时加入忽略大小写参数

Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

boolean contains = pattern.matcher(str).find();

System.out.println("含timeout吗?" + contains); // true

注意:如果是中文的全角半角(比如“TIMEOUT”),这个参数没用,得先把字符串转成小写再匹配(比如str.toLowerCase().contains("timeout"))。

忽略空格:用\s匹配任意空格

比如要找包含“user name”的字符串,不管中间有多少空格(比如“user name”“username”),可以用\s表示“0个或多个空格”:

String str1 = "用户名:user name";

String str2 = "用户名:username";

String regex = "user\sname";

Pattern pattern = Pattern.compile(regex);

// 匹配str1:true(1个空格)

System.out.println(pattern.matcher(str1).find());

// 匹配str2:true(0个空格)

System.out.println(pattern.matcher(str2).find());

我之前帮HR做简历筛选工具时,要找包含“Java 开发”的简历(中间可能有1个或多个空格),就用了这个正则——比拆分成“Java”和“开发”再判断方便多了。

场景3:避免“部分匹配”的边界处理

有时候你要找的是“完整的词”,而不是“部分词”。比如你要找含“apple”的字符串,但不想匹配“apples”(苹果复数)或“pineapple”(菠萝),这时候需要边界处理

正则里的\b表示“单词边界”(即单词字符与非单词字符的分界),比如“\bapple\b”会匹配“apple pie”里的“apple”,但不会匹配“apples pie”或“pineapple”。示例代码:

String str1 = "I like apple"; // 完整的apple

String str2 = "I like apples"; // apple加s

String regex = "\bapple\b";

Pattern pattern = Pattern.compile(regex);

// 匹配str1:true

System.out.println(pattern.matcher(str1).find());

// 匹配str2:false

System.out.println(pattern.matcher(str2).find());

避坑技巧\b只对单词字符(字母、数字、下划线)有效,如果关键词里有非单词字符(比如“#apple”“apple@”),\b就不管用了。这时候可以用负向预查(Negative Lookahead/Lookbehind),比如要匹配“#apple”且前后不是单词字符:

String str1 = "我喜欢#apple"; // 正确匹配

String str2 = "我喜欢a#apple"; // 前面是a(单词字符,不匹配)

String regex = "(?<!\w)#apple(?!\w)";

Pattern pattern = Pattern.compile(regex);

// 匹配str1:true

System.out.println(pattern.matcher(str1).find());

// 匹配str2:false

System.out.println(pattern.matcher(str2).find());

这个技巧我是在Stack Overflow上看到的(链接:https://stackoverflow.com/questions/14008045/java-regex-word-boundary-with-special-characters,加nofollow),上次帮产品做关键词统计时,要找含“#活动”的评论,就用了这个正则——准确过滤了“a#活动”“#活动123”之类的情况。

最后:把常用逻辑封装成工具类,省时间

你肯定不想每次用的时候都写Pattern.compile()Matcher,所以可以把这些逻辑封装成静态工具类——我自己项目里就有个RegexUtils,里面有两个常用方法:

import java.util.regex.Pattern;

import java.util.regex.Matcher;

public class RegexUtils {

// 私有构造方法,防止实例化

private RegexUtils() {}

/

检查字符串是否包含符合正则的子串

@param str 要检查的字符串(可为null)

@param regex 正则表达式(可为null)

@return true:包含;false:不包含或参数为null

/

public static boolean contains(String str, String regex) {

if (str == null || regex == null) return false;

Pattern pattern = Pattern.compile(regex);

Matcher matcher = pattern.matcher(str);

return matcher.find();

}

/

忽略大小写检查字符串是否包含符合正则的子串

@param str 要检查的字符串(可为null)

@param regex 正则表达式(可为null)

@return true:包含;false:不包含或参数为null

/

public static boolean containsIgnoreCase(String str, String regex) {

if (str == null || regex == null) return false;

Pattern pattern = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);

Matcher matcher = pattern.matcher(str);

return matcher.find();

}

}

用的时候直接调用RegexUtils.contains(log, "error")就行——我同事用了这个工具类后,说节省了至少30%的开发时间,不用再记Pattern和Matcher的用法。

为了方便你快速查找,我整理了常用场景的正则对照表,直接拷过去用:

场景 正则表达式 示例匹配
包含“error”(固定字符串) error error_code、请求error、xerrorx
包含“www.”(含特殊字符) www\. www.baidu.com、xwww.yahoo.com
包含“timeout”(忽略大小写) timeout(配合Pattern.CASE_INSENSITIVE) Timeout、TIMEOUT、timeout
包含“user name”(忽略空格) user\sname user name、username、user name
包含完整的“apple”(不匹配apples) \bapple\b apple pie、I like apple、#apple#

这些技巧都是我实际用出来的,没有花架子——比如日志分析、参数校验、敏感词过滤、关键词统计,这些场景都能用。你可以先把工具类拷到项目里,遇到具体问题再调整正则——比如你要找含“123-456”的字符串,记得转义“-”吗?对,正则是“123\-456”,不然“-”在某些情况下会被当作范围符(比如在方括号里)。

如果试了有问题,或者有其他场景想了解,欢迎留言告诉我——毕竟正则这东西,不用是记不住的,多用几次就熟了。


我之前帮朋友做水果订单统计的时候,就碰到过这么个闹心的问题——他想从一堆订单备注里挑出所有提到“apple”的记录,结果导出来的列表里混了好多“apples”(比如“买了3斤apples”)和“pineapple”(比如“想要pineapple汁”),统计的苹果订单量直接多了一倍。后来翻Java正则的文档才搞明白,原来正则默认是“逮着部分就认”的,要找完整的单词,得给它加个“边界标记”b才行。比如把正则写成bappleb,你再试“apple pie”,它会精准匹配中间的“apple”;但碰到“apples”,因为“apple”后面跟着的“s”还是单词字符(字母算单词字符),b就不会把它当成分界,自然就不会错认了;“pineapple”更不用说,前面的“pine”也是单词字符,b直接把它排除在外。

再说得直白点,b就像给单词加了个“隐形的框”——只有当“apple”前后是“非单词字符”的时候,这个框才会生效。比如“#apple”前面是#(非单词字符),后面是空格(非单词字符),b就认这是完整的“apple”;但“apples”后面是s(单词字符),框就不生效,正则也就不会匹配。你要是碰到类似“想找完整关键词”的情况,比如检查用户名里有没有“Tom”而不是“Tommy”,或者日志里有没有“error”而不是“errorcode”,直接加b就行,比自己写一堆判断条件省心多了。


find()和matches()的核心区别是什么?

find()用于检查字符串中是否“包含”符合正则的子串(只要有某部分匹配就返回true);matches()则用于检查字符串是否“完全等于”正则表达式(整个字符串必须100%匹配才返回true)。比如要验证“aabcf”里有“abc”,用find()会返回true,用matches()会返回false。

Java正则里哪些特殊字符需要转义?

正则中的特殊字符包括:.(任意字符)、(前面字符出现0次或多次)、+(前面字符出现1次或多次)、?(前面字符出现0次或1次)、|(逻辑或)、()(分组)、[](字符集)、{}(重复次数)、^(字符串开头)、$(字符串 )、(转义符本身)。转义时需要在字符前加两个反斜杠(\),比如匹配“.”要写“\.”。

如何忽略大小写验证字符串包含某内容?

可以在编译正则时加入Pattern.CASE_INSENSITIVE参数,比如验证“Timeout”里有“timeout”,用Pattern.compile(“timeout”, Pattern.CASE_INSENSITIVE).matcher(str).find()即可返回true。 这个参数仅对ASCII字符(如a-z、A-Z)有效,中文全角半角需额外处理。

怎么避免正则匹配到“部分单词”(比如想匹配“apple”却匹配到“apples”)?

可以用正则的“单词边界”(\b),比如要匹配完整的“apple”,正则写“\bapple\b”,这样会匹配“apple pie”里的“apple”,但不会匹配“apples”或“pineapple”。\b的作用是区分单词字符(字母、数字、下划线)与非单词字符的分界。

封装的RegexUtils工具类可以直接用吗?需要注意什么?

可以直接复制到项目中使用,工具类中的contains()和containsIgnoreCase()方法已经处理了null参数(若str或regex为null直接返回false)。使用时只需传入要检查的字符串和正则表达式,比如RegexUtils.contains(log, “error”)就能快速判断日志是否含“error”。若需要扩展其他场景(如匹配完整单词),可以在工具类中新增方法。

温馨提示:本站提供的一切软件、教程和内容信息都来自网络收集整理,仅限用于学习和研究目的;不得将上述内容用于商业或者非法用途,否则,一切后果请用户自负,版权争议与本站无关。用户必须在下载后的24个小时之内,从您的电脑或手机中彻底删除上述内容。如果您喜欢该程序和内容,请支持正版,购买注册,得到更好的正版服务。我们非常重视版权问题,如有侵权请邮件与我们联系处理。敬请谅解! 联系邮箱:lgg.sinyi@qq.com

给TA打赏
共{{data.count}}人
人已打赏
行业资讯

AI分时顶底指标精准源码|免费获取|实战验证有效

2025-9-10 18:02:32

行业资讯

免费源码编辑器官方网站入口直接使用

2025-9-10 18:34:23

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索