简体   繁体   中英

Match regex string not between 2 strings

I'm trying to find jQuery strings that not properly wrapped in $(document).ready( or $(function() .

So it would match this:

console.log('something');
$('button').trigger('click');
$('div').css('color','red');
console.log('something else');

but it would not match this:

$(document).ready(function(){
  // More js here
  $('label').trigger('click');
  $('div.something').text('hello');
  // more js here
});

or this

$(function(){
  $('.test').append('<div>taco</div>');
});

I've tried doing something this like:

(?=\$\(document)[\s\S]*\$\([\s\S]*\}\)

But it did sort of the opposite of what I wanted... Not sure how todo the inverse...

I don't know how you would do this using one RegEx, but you're already (close to) half way to being able to do it using two.

First, find any occurrences of the blocks you would like to exclude, and replace them with an empty string.

I would use the following RegEx:

( RegEx101 Test Case )

/(?:\$|jQuery)\((?:document\)\.ready\()?function.*?\(\){(?:[^{]|{[^]*}\);?)+}\);?/gi

在此处输入图片说明

Let's break that down:

  • (?:\\$|jQuery) looks for "$" or "jQuery",
  • \\( looks for "(",
  • (?:document\\)\\.ready\\()? optionally looks for "document).ready(",
  • function looks for "function",
  • .*? looks for zero or more anythings non-greedily (normally function would just be followed by () , but sometimes named functions are used like function namedFunc() ),
  • \\(\\){ looks for "(){",
  • (?:[^{]|{[^]*}\\);)+ looks for one or more:
    • [^{] looks for a character that is not "{", or:
      • { looks for the "{" symbol, followed by
      • [^]* looks for zero or more not-nothings (I would use .* , but that doesn't match new lines), followed by,
      • }\\);? looks for "})" with an optional ";",
  • }\\);? looks for "})" with an optional ";",
  • g is a flag that tells the RegEx engine to search for multiple matches,
  • i is a flag that tells the RegEx engine to search in a case-insensitive manner

Once you've replaced all matches, you can search for your jQuery commands. The RegEx to do this is much simpler than the previous RegEx.

( RegEx101 Test Case )

/(?:\$|jQuery)[(.].*?[;\n]/gi

在此处输入图片说明

Lets break that down:

  • (?:\\$|jQuery) looks for "$" or "jQuery",
  • [(.] looks for "(" or ".",
  • .*? looks for zero or more anythings non-greedily,
  • [;\\n] looks for ";" or "\\n",
  • g is a flag that tells the RegEx engine to search for multiple matches,
  • i is a flag that tells the RegEx engine to search in a case-insensitive manner

Here's an example script that uses these two RegExes to find the commands in the sample input you have provided. Check out the two RegEx101.com test cases I've provided above to see how it will work with some different cases.

 var regexes = [ // https://regex101.com/r/dO7qR7/7 lots more tests here /(?:\\$|jQuery)\\((?:document\\)\\.ready\\()?function.*?\\(\\){(?:[^{]|{[^]*}\\);?)+}\\);?/gi, // https://regex101.com/r/dO7qR7/8 /(?:\\$|jQuery)[(.].*?[;\\n]/gi ], match, matches = []; var string = [ "console.log('something');", "$('button').trigger('click');", "$('div').css('color','red');", "console.log('something else');", "", "$(document).ready(function(){", " // More js here", " $('label').trigger('click');", " $('div.something').text('hello');", " // more js here", "});", "", "$(function(){", " $('.test').append('<div>taco</div>');", "});" ].join('\\n'); console.log(string); string = string.replace(regexes[0], ''); console.log(string); while(match = regexes[1].exec(string)) matches.push(match[0]); console.log(matches); // ["$('button').trigger('click');", "$('div').css('color','red');"] 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM