正则表达式如何精准筛选任意字符串末尾指定精确长度的字符序列
匹配末尾恰好2个
s的字符串正则方案 明确匹配规则
- 仅当字符串**末尾刚好是2个连续
s,且这两个s之前紧邻的字符不是s**时返回true- 返回false的反例:
foo、foos、foosss、sometexts、sometextsss、sss - 返回true的正例:
fooss、barss、sometextss、ss
- 返回false的反例:
- 字符串开头、中间位置允许出现任意数量的
s,不做额外限制
原有写法的问题
- 贪婪模式
.*s{2}:.*会尽可能多匹配字符,遇到foosss这类末尾3个s的字符串时,.*会吞掉前4个字符foos,把最后2个s留给s{2}匹配,直接误判。 - 非贪婪模式
.*?s{2}:非贪婪匹配会从最短前缀开始尝试,匹配失败就回溯,只要字符串任意位置存在连续2个s就可能命中,完全无法限定这两个s在字符串末尾,依然会误判。
正确正则
通用兼容写法(无断言,支持所有正则引擎)
^(.*[^s])?s{2}$
如果是Java中使用String.matches()方法(该方法默认要求匹配整个字符串),可以省略首尾的^和$,直接写:
boolean isMatch = str.matches("(.*[^s])?s{2}");
写法逻辑拆解
(.*[^s])?:可选匹配组,匹配任意长度前缀,要求前缀最后一个字符不能是s——从根源上避免末尾出现3个及以上连续s的情况;分组设为可选是为了兼容字符串本身就是ss(长度为2,无前置字符)的边界场景s{2}:匹配2个连续的s$:锚定字符串结尾,保证匹配到的2个s刚好在字符串最末端
测试验证
| 测试字符串 | 匹配结果 | 是否符合预期 |
|---|---|---|
foo | false | 是 |
foos | false | 是 |
foosss | false | 是 |
fooss | true | 是 |
barss | true | 是 |
sometexts | false | 是 |
sometextsss | false | 是 |
sometextss | true | 是 |
ss | true | 是 |
sss | false | 是 |
内容的提问来源于stack exchange,提问作者Gavin Walker
相关产品推荐
相关产品推荐

