scenario

Sometimes we need to match some character, but we don’t want to match the character in the end result. In this case, using the zero-width assertion of the re can achieve the desired effect

Concept: What isZero width assertion?

  • Zero-width: as the name suggests, a zero-width match, meaning that what it matches is not saved in the match result,
  • Assertion: The assumption made by a regular expression can be regarded as a condition judgment of the regular expression. (Only when this condition is met can the regular expression match successfully.) I will use examples to verify this statement

classification

  • According to the writing position:
    • Antecedent assertion (written after the result) : Matches the previous result if the condition is true
    • Postmortem assertion (use<Symbol, written before results) : Matches subsequent results if the condition is true
  • Conditional classification (whether zero-width assertions can match)
    • Forward: match (use=)
    • Negative: does not match (use!)

The following zero-width assertion format is combined based on position and condition

  1. a(? =b) : the purpose is to matcha, but it requires theaBe sure to include characters after itbTo match (match a if a is followed by b)
  2. a(? ! B) : The purpose should matcha, but it requires theaBehind a certainCan’tContains charactersbTo match (ditto)
  3. (? <=b)a: The purpose is to matcha, but it requires theaBe sure to include characters before itbTo match (ditto)
  4. (? <! B) A: The purpose should matcha, but it requires theaIn front of a certainCan’tContains charactersbTo match (ditto)

application

  • Replace the characters in the double curly braces with the corresponding data
    const template = Name: {{username}}, age: {{age}} '
    const user = {username:'laoxie'.age:18}
    
    / / if [a-z] + front matching ` {{` behind and matching `}} ` to the result of the match [a-z] +, but ` {{` and `}} ` will not enter the final match
    const reg = / (? <=\{\{)[a-z]+(? =\}\})/g
    const result = template.replace(reg,(key) = >{
        return user[key]
    })
    console.log(result); // => Name: {{laoxie}} age: {{18}}
Copy the code
  • Add a comma to the amount to make it easier to read (e.g. 1000000 -> 1,000,000)
    const amount = '1000000'
    amount.replace(/\B(? =(\d{3})+(? ! \d))/g.', ') // => 1,000,000

    // > Description: '\B' matches a non-word boundary (i.e. the position between two numbers)
    // If zero width assertion is not used, the following result is obtained
    amount.replace(/\B/g.', '); / /,0,0,0,0,0,0 = > 1
    
    \B is replaced with a comma ', 'if there are three more digits after \B and no more digits after \B
Copy the code

So, using zero-width assertions properly can make our regular matching more powerful, and it’s time to show the real technique

Postassertion in PS: JS is only supported in ES9, note browser support