skip to Main Content

I’m trying to create a regex that matches 8 character words that contain at 3 least instances of a digit or the ‘%’ symbol and whitespace after the word.

The following strings should match:

  • ‘ab1d2f3h ‘
  • ‘ab%d2f3h ‘
  • ‘ab%d%f3h ‘
  • ‘ab%d%f%h ‘

The regex I have so far looks like this:

const string = 'this word ab1d2f3h needs to go, but not this word abcdefgh %%%'.replace(/(?=(?:D*(d|%)){3})(w|%){8}s/g, '%%%%%%%% ')

If I remove ‘%%%’ from the string, it works – ‘ab1d2f3h ‘ is replaced. However, if ‘%%%’ is present in the string, it also replaces ‘abcdefhg ‘, which I don’t want to happen.

Does anyone know the proper regex for this?

2

Answers


  1. Chosen as BEST ANSWER

    Asked ChatGPT and it answered my question:

    You can use the following regular expression to match 8 character words containing at least 3 instances of a digit or the symbol '%':

    b(?=(w*[d%]){3})w{8}b
    

    Explanation:

    • b matches a word boundary to ensure that the regex only matches whole words.
    • (?=(w*[d@]){3}) is a positive lookahead assertion that checks for the presence of at least 3 instances of a digit or the symbol '@' in the word.
    • w{8} matches any 8 word characters (letters, digits, and underscores).
    • b matches the end of the word boundary.

    Note that this regex assumes that there are no spaces or other non-word characters in the string. If there are, you may need to modify the regex to handle them.


  2. If a lookbehind assertion is supported in the environment where you are using the pattern:

     (?<!S)(?=S{8}s)(?:[^sd%]*[%d]){3}S*
    

    Explanation

    • (?<!S) Positive lookbehind, assert a whitspace boundary to the left
    • (?=S{8}s) positive lookahead, assert 8 non whitespace chars followed by a whitespace char (note that it can also match a newline)
    • (?:[^sd%]*[%d]){3} Repeat 3 times matching any non whitespace chars except a digit or % and then match either a digit or %
    • S* Match optional non whitespace chars

    Regex demo

    Or using a capture group:

    (^|s)(?=S{8}s)(?:[^sd%]*[%d]){3}S*
    

    Regex demo

    In the replacement use the first capture group to keep the leading whitspace char.

    const string = 'this word ab1d2f3h needs to go, but not this word abcdefgh %%%'.replace(/(^|s)(?=S{8}s)(?:[^sd%]*[%d]){3}S*/g, '$1%%%%%%%%')
    console.log(string)
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search