javascript regex - look behind alternative?

前端 未结 6 1870
时光取名叫无心
时光取名叫无心 2020-11-22 05:44

Here is a regex that works fine in most regex implementations:

(?

This matches .js for a string which ends with .js exc

相关标签:
6条回答
  • 2020-11-22 06:25

    If you can look ahead but back, you could reverse the string first and then do a lookahead. Some more work will need to be done, of course.

    0 讨论(0)
  • 2020-11-22 06:25

    This is an equivalent solution to Tim Pietzcker's answer (see also comments of same answer):

    ^(?!.*filename\.js$).*\.js$
    

    It means, match *.js except *filename.js.

    To get to this solution, you can check which patterns the negative lookbehind excludes, and then exclude exactly these patterns with a negative lookahead.

    0 讨论(0)
  • 2020-11-22 06:28

    Below is a positive lookbehind JavaScript alternative showing how to capture the last name of people with 'Michael' as their first name.

    1) Given this text:

    const exampleText = "Michael, how are you? - Cool, how is John Williamns and Michael Jordan? I don't know but Michael Johnson is fine. Michael do you still score points with LeBron James, Michael Green Miller and Michael Wood?";
    

    get an array of last names of people named Michael. The result should be: ["Jordan","Johnson","Green","Wood"]

    2) Solution:

    function getMichaelLastName2(text) {
      return text
        .match(/(?:Michael )([A-Z][a-z]+)/g)
        .map(person => person.slice(person.indexOf(' ')+1));
    }
    
    // or even
        .map(person => person.slice(8)); // since we know the length of "Michael "
    

    3) Check solution

    console.log(JSON.stringify(    getMichaelLastName(exampleText)    ));
    // ["Jordan","Johnson","Green","Wood"]
    

    Demo here: http://codepen.io/PiotrBerebecki/pen/GjwRoo

    You can also try it out by running the snippet below.

    const inputText = "Michael, how are you? - Cool, how is John Williamns and Michael Jordan? I don't know but Michael Johnson is fine. Michael do you still score points with LeBron James, Michael Green Miller and Michael Wood?";
    
    
    
    function getMichaelLastName(text) {
      return text
        .match(/(?:Michael )([A-Z][a-z]+)/g)
        .map(person => person.slice(8));
    }
    
    console.log(JSON.stringify(    getMichaelLastName(inputText)    ));

    0 讨论(0)
  • 2020-11-22 06:32

    EDIT: From ECMAScript 2018 onwards, lookbehind assertions (even unbounded) are supported natively.

    In previous versions, you can do this:

    ^(?:(?!filename\.js$).)*\.js$
    

    This does explicitly what the lookbehind expression is doing implicitly: check each character of the string if the lookbehind expression plus the regex after it will not match, and only then allow that character to match.

    ^                 # Start of string
    (?:               # Try to match the following:
     (?!              # First assert that we can't match the following:
      filename\.js    # filename.js 
      $               # and end-of-string
     )                # End of negative lookahead
     .                # Match any character
    )*                # Repeat as needed
    \.js              # Match .js
    $                 # End of string
    

    Another edit:

    It pains me to say (especially since this answer has been upvoted so much) that there is a far easier way to accomplish this goal. There is no need to check the lookahead at every character:

    ^(?!.*filename\.js$).*\.js$
    

    works just as well:

    ^                 # Start of string
    (?!               # Assert that we can't match the following:
     .*               # any string, 
      filename\.js    # followed by filename.js
      $               # and end-of-string
    )                 # End of negative lookahead
    .*                # Match any string
    \.js              # Match .js
    $                 # End of string
    
    0 讨论(0)
  • 2020-11-22 06:32

    Let's suppose you want to find all int not preceded by unsigned:

    With support for negative look-behind:

    (?<!unsigned )int
    

    Without support for negative look-behind:

    ((?!unsigned ).{9}|^.{0,8})int
    

    Basically idea is to grab n preceding characters and exclude match with negative look-ahead, but also match the cases where there's no preceeding n characters. (where n is length of look-behind).

    So the regex in question:

    (?<!filename)\.js$
    

    would translate to:

    ((?!filename).{8}|^.{0,7})\.js$
    

    You might need to play with capturing groups to find exact spot of the string that interests you or you want't to replace specific part with something else.

    0 讨论(0)
  • 2020-11-22 06:33

    ^(?!filename).+\.js works for me

    tested against:

    • test.js match
    • blabla.js match
    • filename.js no match

    A proper explanation for this regex can be found at Regular expression to match string not containing a word?

    Look ahead is available since version 1.5 of javascript and is supported by all major browsers

    Updated to match filename2.js and 2filename.js but not filename.js

    (^(?!filename\.js$).).+\.js

    0 讨论(0)
提交回复
热议问题