如何用正则表达式(regexp)匹配字符串中指定单词的变位词?
问题解答
首先明确:可以用正则选中所有符合要求的变位词,但你写的正则只是匹配单个a/b/c字符,完全没贴合"变位词(即包含且仅包含a、b、c各一次的3字符连续序列)"的需求,所以得不到预期结果。
正确的正则写法
要匹配bca的变位词,核心是匹配恰好包含a、b、c各一个的3长度连续子串,可以用正向预查来保证三个字符都存在,再匹配任意排列的三个目标字符:
const str = 'abcadbca'; // 正则逻辑:先确保当前位置后有a、b、c,再匹配连续3个a/b/c字符 const reg = /(?=.*a)(?=.*b)(?=.*c)[abc]{3}/g; const matches = str.match(reg); console.log(matches); // 输出: ["abc", "bca"]
正则拆解
(?=.*a):正向预查,确认当前位置及之后存在字符a(?=.*b):同理,确认存在字符b(?=.*c):同理,确认存在字符c[abc]{3}:匹配连续3个属于a、b、c的字符
你提到输入里有3个符合的变位词,但实际abcadbca的字符序列是a b c a d b c a,其中只有索引0-2的abc、索引5-7的bca符合要求,中间的adb、dbc都不满足"包含a、b、c各一次"的条件,可能是你对输入序列的判断有误。
重叠匹配的处理
如果需要支持重叠匹配(比如输入是abcabc,想捕获abc、bca、cab、abc这类重叠的符合项),默认的match会跳过已匹配字符,这时候需要结合循环和手动调整匹配位置来实现:
const str = 'abcabc'; const reg = /(?=((?=.*a)(?=.*b)(?=.*c)[abc]{3}))/g; const matches = []; let match; while ((match = reg.exec(str)) !== null) { matches.push(match[1]); // 每次匹配后向后移动1位,允许重叠匹配 reg.lastIndex = match.index + 1; } console.log(matches); // 输出: ["abc", "bca", "cab", "abc"]
你的原有代码问题
你写的/(a|b|c)/g只会逐个匹配字符串里的a、b、c单个字符,得到的结果是["a","b","c","a","b","c","a"],完全没有筛选出"包含三个不同字符各一次的连续子串",自然和预期结果不符。
内容的提问来源于stack exchange,提问作者3gwebtrain
相关产品推荐
相关产品推荐

