David
David

Reputation: 131

Counting all substring cases in a string

I am counting the occurrence of specific keypairs in a word

console.log("acceptable".match(/ab|ac|ar/gi).length); //2

(picture) Example of just keypairs on regex101.com

This works as expected, but including anchored single letters, like "^a" overwrites other matches:

console.log("acceptable".match(/^a|ab|ac|ar/gi).length); //2, should be 3 

(picture) Example of keypairs on regex101.com

As the regex101.com example shows, the ^a overwrites the ac match, so only 2 matches are found. I need to count every instance, even duplicates like "^a" as a substring of "ab". I can solve this without regex, but regex is more elegant.

Any help will be greatly appreciated.

Upvotes: 3

Views: 63

Answers (2)

The fourth bird
The fourth bird

Reputation: 163267

You could use a positive lookahead with an alternation to check for an a at the start of the string and capture the values in capture groups, which you can check for in the code.

(?=(a[bcr])|(?<=^(a)))
  • (?= positive lookahead
    • (a[bcr]) Capture group 1, match either ab ac or ar
    • | Or
    • (?<=^(a)) Positive lookbehind, capture a in group 2
  • ) Close positive lookahead

Regex demo

const regex = /(?=(a[bcr])|(?<=^(a)))/gmi;
const str = `acceptable`;
let res = Array.from(str.matchAll(regex), m => m[2] ? m[2] : m[1]);
console.log(res)
console.log(res.length)

Upvotes: 1

Jakob Maynard
Jakob Maynard

Reputation: 1

I don't believe there is a way to do it within a single regex, where one match is a substring of another and have it return both. I would chain 2 patterns like this:

let string = 'acceptable';
let pattern1 = /a(b|c|r)/gi;
let pattern2 = /^a/gi;

let output = string.match(pattern1).length + string.match(pattern2).length;
console.log(output); // returns 3

Upvotes: 0

Related Questions