必须用锚定正则^[a-z][a-zA-Z0-9]+(__[a-z][a-zA-Z0-9]+)?(--[a-z][a-zA-Z0-9]+)?$并白名单扩展u-|is-|js-前缀,否则.btn-primary等违规写法将漏检;但该正则仅校验格式,无法识别语义归属与结构合法性,须配合stylelint-selector-bem-pattern插件及preset、componentName、ignoreSelectors三项完整配置。
直接套最新示例正则会放过 .btn-primary、.userList、.card__header__logo 这类明显违规写法。关键在三点:必须锚定开头结尾、强制小写开头、禁止非法嵌套。
推荐基础 BEM 正则:^[a-z][a-zA-Z0-9]+(__[a-z][a-zA-Z0-9]+)?(--[a-z][a-zA-Z0-9]+)?$
^[a-z]:块名必须小写字母开头,拒绝 .Card、.1button
__[a-z]:元素名也必须小写开头,拒绝 .block__Header
(--[a-z])?:修饰符只允许一层,拒绝 .block__elem--large--dark
$ 就会把 .card__title extra-class 里的前半段当合法——实际它只是字符串片段项目里不可能只有纯 BEM 类,.u-text-center、.is-open、.js-toggle 必须白名单放行,否则全报错。硬塞进同一正则里会导致规则膨胀、难维护。
正确做法是用逻辑或组合:^(u-[a-z][a-zA-Z0-9]+|is-[a-z][a-zA-Z0-9]+|js-[a-z][a-zA-Z0-9]+|([a-z][a-zA-Z0-9]+(__[a-z][a-zA-Z0-9]+)?(--[a-z][a-zA-Z0-9]+)?)$)
u-、is-、js-,开头必须带 ^ 防止 .button-is-active 被误放过.Block__elem 漏检class-name-pattern——这是 v13 旧字段,v14+ 会直接报 Invalid options object
selector-class-pattern 只做字符串匹配,它不管 .card__image 是否真有对应 .card 块,也不拦 .card__header__title 这种非法三级嵌套。
.card__image--loading 和 .card--loading 都能过同一正则,但后者才是合法修饰符位置.userList 若正则没禁驼峰,就会被当成 userList(小写开头+字母数字)放过.btn-primary 匹配 [a-z]+-[a-z]+?那它就不是 BEM,而是 SUIT 或自定义风格——正则无法判断意图真正要查“这个 element 是否属于这个 block”,必须用 stylelint-selector-bem-pattern 插件,并配齐 preset、componentName、ignoreSelectors 三项,缺一不可。
selector-class-pattern 只扫 CSS 文件里的静态选择器,对 JS 中 :class="['card', `card--${status}`]" 这类拼接完全无感——card--loading 缺双下划线也不会报。
const bem = (block, elem?, mod?) => `${block}${elem ? '__' + elem : ''}${mod ? '--' + mod : ''}`
className={`btn btn--${theme} ${hasIcon ? 'btn__icon' : ''}`} 里空格错误、btn__icon 脱离上下文,正则都发现不了eslint-plugin-bem 并配置类型约束,否则 TS 也无法拦截运行时字符串正则校验只是第一道防线,它快、轻量、编辑器友好,但边界清晰:只管“长得像不像”,不管“是不是真的”。想查结构合法性,就得插件上,且得配全参数——少一个,.btn-primary 就安静地躺在代码里。
tlwdr7650路由器没有wps按钮(tlwdr7650路由器没有wps按钮怎么办)
tlwdr7632扩展器电脑怎么设置(tlwdr7632扩展器电脑设置方法)
tlwda6332re安装教程(tlwda6332re如何安装)
tlwdr7632扩展器手机怎么设置(tlwdr7632扩展器手机设置方法)
tlxdr3010怎么设置网速快(tlxdr3010网速快设置方法)
tlwdr5620易展版怎么克隆(tlwdr5620易展版克隆方法)