Single RegEx to catch multiple options and replace with their corresponding replacements

837 Views Asked by At

The problem goes like this:

value match: 218\d{3}(\d{4})@domain.com replace with 10\1 to get 10 followed by last 4 digits for example 2181234567 would become 104567

value match: 332\d{3}(\d{4})@domain.com replace with 11\1 to get 11 followed by last 4 digits for example 3321234567 would become 114567

value match: 420\d{3}(\d{4})@domain.com replace with 12\1 to get 12 followed by last 4 digits ..and so on for example 4201234567 would become 124567

Is there a better way to catch different values and replace with their corresponding replacements in a single RegEx than creating multiple expressions?

Like (218|332|420)\d{3}(\d{4})@domain.com to replace 10\4|11\4|12\4) and get just their corresponding results when matched.

Edit: Didn't specify the use case: It's for my PBX, that just uses RegEx to match patterns and then replace it with the values I want it to go out with. No code. Just straight up RegEx in the GUI. Also for personal use, if I can get it to work with Notepad++

3

There are 3 best solutions below

1
Peter Thoeny On

I don't think you can use a single regular expression to conditionally replace text as per your example. You either need to chain multiple search & replace, or use a function that does a lookup based on the first captured group (first three digits).

You did not specify the language used, regular expressions vary based on language. Here is a JavaScript code snippet that uses the function with lookup approach:

var str1 = '[email protected]';
var str2 = '[email protected]';
var str3 = '[email protected]';
var strMap = {
  '218': '10',
  '332': '11',
  '420': '12'
  // add more as needed
};
function fixName(str) {
  var re = /(\d{3})\d{3}(\d{4})(?=\@domain\.com)/;
  var result = str.replace(re, function(m, p1, p2) {
    return strMap[p1] + p2;
  });
  return result;
}
var result1 = fixName(str1);
var result2 = fixName(str2);
var result3 = fixName(str3);
console.log('str1: ' + str1 + ', result1: ' + result1);
console.log('str2: ' + str2 + ', result2: ' + result2);
console.log('str3: ' + str3 + ', result3: ' + result3);

Output:

str1: [email protected], result1: [email protected]
str2: [email protected], result2: [email protected]
str3: [email protected], result3: [email protected]
0
Toto On
  • Ctrl+H
  • Find what: (?:(218)|(332)|(420))\d{3}(\d{4})(?=@domain\.com)
  • Replace with: (?{1}10$4)(?{2}11$4)(?{3}12$4)
  • CHECK Wrap around
  • CHECK Regular expression
  • Replace all

Explanation:

(?:                 # non capture group
    (218)               # group 1, 218
  |                 # OR
    (332)               # group 2, 332
  |                 # OR
    (420)               # group 3, 420
)                   # end group
\d{3}               # 3 digits
(\d{4})             # group 4, 4 digits
(?=@domain\.com)    # positive lookahead, make sure we have "@domain.com" after
                    # that allows to keep "@domain.com"
                    # if you want to remove it from the result, just put "@domain\.com"
                    # without lookahead.

Replacement:

(?{1}               # if group 1 exists
    10                  # insert "10"
    $4                  # insert content of group 4
)                   # endif
(?{2}11$4)          # same as above
(?{3}12$4)          # same as above

Screenshot (before):

enter image description here

Screenshot (after):

enter image description here

0
Mikaël Mayer On

@Toto has a nice answer, and there is another method if the operator (?{1}...) is not available (but thanks, Toto, I did not know this feature of NotePad++). More details on my answer here: https://stackoverflow.com/a/63676336/1287856

Append to the end of the doc:

,218=>10,332=>11,420=>12

Search for:

(218|332|420)\d{3}(\d{4})([email protected])(?=[\s\S]*,\1=>([^,]*))

Replace with

\3\2

watch in action: Multiple replacements in Notepad++