如何编写正则表达式仅允许字母数字和#且#最多出现1次?
你的现有正则存在逻辑错误:你写的^(?!(.*#){1})^[a-zA-Z0-9#]*$里的负向预查规则是匹配完全不存在#的字符串,无法满足允许#最多出现1次的需求。
你可以用^[a-zA-Z0-9]*#?[a-zA-Z0-9]*$实现需求,规则说明:
^匹配字符串起始位置[a-zA-Z0-9]*匹配0个或多个大小写字母、数字,对应#号出现前的合法字符#?匹配0次或1次#号,直接限制#号最多只能出现1次[a-zA-Z0-9]*匹配0个或多个大小写字母、数字,对应#号出现后的合法字符$匹配字符串结束位置
这个规则天然排除了除#外的所有特殊字符,同时严格限制#的出现次数不超过1次。
修正后的Java代码如下:
import java.util.ArrayList; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; public class Test { public static void main(String[] args) { List<String> names = new ArrayList<String>(); names.add("GSDAHA"); names.add("AGE2"); names.add("257#ASDF"); names.add("302#JBMTU#"); // #出现2次,不符合规则 names.add("ABC<DE"); // 含非法特殊字符<,不符合规则 String regex = "^[a-zA-Z0-9]*#?[a-zA-Z0-9]*$"; Pattern pattern = Pattern.compile(regex); for (String name : names) { Matcher matcher = pattern.matcher(name); System.out.println(name + " => " + matcher.matches()); } } }
运行后输出完全符合你的预期:
- GSDAHA => true
- AGE2 => true
- 257#ASDF => true
- 302#JBMTU# => false
- ABC<DE => false
如果你偏好使用预查写法,也可以用^(?!(.*#){2})[a-zA-Z0-9#]+$,通过负向预查直接排除出现2次及以上#的场景,效果完全一致。
内容的提问来源于stack exchange,提问作者Imran khan
相关产品推荐
相关产品推荐

