1

For example:

I want to match duplicate characters that are separated by other characters:

  • Matching stress should return sss
  • Matching lambda should return aa
  • Matching moonmen should return moonmn

I am close, getting the first character of every duplicate by using lookaheads:

Regex101 link

['stress','lambda','moonmen'].forEach( (e) => {
  console.log( e.match(/(.)(?=.*\1)/g) )
} )

But how would I get all duplicate characters?

TheWandererLee
  • 1,012
  • 5
  • 14
  • 2
    Regex is not usually for this kind of task, it is inefficient and requires code tweaks anyway as you cannot achieve this "in one regex go". – Wiktor Stribiżew Jul 23 '19 at 20:18
  • 1
    The regex could be simplified if you sort the characters first. –  Jul 23 '19 at 20:26
  • [(\[a-zA-Z\])(?=(?:(?!\1).)+\1)](https://regex101.com/r/hz3m0j/1) –  Jul 23 '19 at 22:23

2 Answers2

3

Your pattern matches the latest character that has a duplicate.

As an alternative, knowing that they have a duplicate, you could use a negated character class to remove all the non duplicates.

let pattern = /(.)(?=.*\1)/g;
[
  "stress",
  "lambda",
  "moonmen"
].forEach(s => {
  let regex = new RegExp("[^" + [...new Set(s.match(pattern))].join('') + "]+", "g");
  console.log(s.replace(regex, ''));
});

If you want to account for special characters in the string, you might use the function on this page to escape characters with special meaning.

The fourth bird
  • 154,723
  • 16
  • 55
  • 70
1

This is pretty complex, my guess is that maybe this expression might be an step closer:

(?:(.)(?=(.*)\1))

DEMO

Emma
  • 27,428
  • 11
  • 44
  • 69