如何找出多个字符串中存在的未知公共模式?
多字符串公共子串查找方案(适配微前端CSS验证场景)
可行性说明
完全可行,你的需求本质是**最长公共子串(Longest Common Substring)**查找问题,通过遍历字符串即可确定所有输入的公共片段。
现成方法与实现选择
JavaScript原生API没有直接提供该功能,但可以通过两种方式解决:
- 轻量场景:自行实现基础算法:逻辑简单,无需引入第三方库,适合Jenkins流水线这类需要轻量脚本的环境。
- 复杂场景:使用第三方库:如果需要处理大量字符串或更复杂的子串匹配(如忽略大小写、正则匹配),可以选择专门的字符串处理库,但多数情况下自行实现足够满足需求。
核心实现思路
以最长公共子串为例,核心逻辑如下:
- 选取输入字符串中最短的那个作为基准(公共子串长度不可能超过最短字符串)。
- 从最长到最短遍历基准字符串的所有可能子串。
- 检查每个子串是否存在于所有其他输入字符串中,第一个满足条件的即为最长公共子串。
- 若需判断是否存在符合预期的模式(如
[_ngcontent=...]),可在找到公共子串后额外做格式校验。
适配你的CSS验证场景的代码示例
1. 基础最长公共子串查找函数
function findLongestCommonSubstring(strings) { if (strings.length === 0) return ''; // 取最短字符串作为基准,减少遍历次数 const shortestStr = strings.reduce((a, b) => a.length <= b.length ? a : b); let longestMatch = ''; // 从最长可能的子串长度开始遍历 for (let len = shortestStr.length; len > 0; len--) { for (let start = 0; start <= shortestStr.length - len; start++) { const candidate = shortestStr.substring(start, start + len); // 检查所有字符串是否包含当前子串 const allContain = strings.every(str => str.includes(candidate)); if (allContain) { longestMatch = candidate; return longestMatch; // 找到最长匹配直接返回,提升效率 } } } return longestMatch; }
2. 结合CSS规则解析的场景化实现
针对你通过document.styleSheets获取CSS规则的需求,先提取选择器文本再查找公共子串,避免误匹配样式内容:
// 从页面styleSheets中提取所有样式规则的选择器文本 function extractAllSelectorTexts() { const selectors = []; for (const sheet of document.styleSheets) { try { // 跨域样式表会抛出权限错误,直接跳过 for (const rule of sheet.cssRules) { if (rule.type === CSSRule.STYLE_RULE) { selectors.push(rule.selectorText); } } } catch (e) { continue; } } return selectors; } // 执行验证逻辑 const cssSelectors = extractAllSelectorTexts(); const commonSubstring = findLongestCommonSubstring(cssSelectors); // 判断是否为目标ngcontent属性选择器 if (commonSubstring.includes('_ngcontent') && commonSubstring.startsWith('[') && commonSubstring.endsWith(']')) { console.log(`检测到公共Shadow DOM样式前缀: ${commonSubstring}`); } else { console.log('未找到公共Shadow DOM前缀,存在全局CSS污染风险'); }
模式存在性判断
- 如果上述函数返回的公共子串长度大于设定的阈值(比如大于10,排除短的无意义公共字符),且符合
[_ngcontent=...]的格式,则说明存在目标模式。 - 如果返回空串或短子串,则说明不存在统一的公共前缀,需要警惕未隔离的全局CSS规则。
内容的提问来源于stack exchange,提问作者codepleb
相关产品推荐
相关产品推荐

