Regular expression is a clever tool, often used to find and replace in the string, JavaScript language reference Perl, also provides regular expression related modules, development is very practical, in some class libraries or frameworks, such as jQuery, there are a lot of regular expressions, so learn regular expression, Is a basic requirement to improve development skills. So today, the blogger will summarize the relevant knowledge of regular expression in detail, hoping that students who are not familiar with regular expression can also master the principle and application of regular expression.

In JS, there are two ways to create regular expressions: literal and constructor, as shown below:

var regex = /\w+/; Var regex = new RegExp('\\w+');Copy the code

You may have noticed, the use of literal is much more than the constructor is concise, \ w said a word, matching the individual letters, Numbers, or underscores, and use the RegExp the constructor, our regular into the \ \ “” w”, said this is because in a string to a backslash \, we need to escape, which is in the front, and an escape character \. Believe we all know, a match in literal regular expression backslash \ regular, just written \ \ so, but the regular in the string expression, is “\ \ \ \” like this, this is because the string of the top two said a backslash \, the latter two also said a backslash \, finally in the regular level, the result still \ \.

Postfix modifiers can be added to each of the above creation forms, which can be used singly or in combination:

/\w+/g; // global search
/\w+/i; // ignore case
/\w+/m; // multi-line
/\w+/u; // unicode
/\w+/y; // sticky

/\w+/gi;
new RegExp('\\w+'.'gi');Copy the code

From the point of comment in English, believe that everyone’s probably all know a little, it is important to note the u and y modifier, new features, they are ES6 u said enable Unicode mode, especially useful for matching Chinese, and y is sticky, the meaning of “touching”, said the next match goal after the match, we will introduce later.

Canonical correlation method

Now that YOU have regular expression objects, how do you use them? The regular and string methods in JS both provide methods in the prototype. Let’s look at two methods in the regular prototype:

RegExp.prototype.test(str);
RegExp.prototype.exec(str);Copy the code

The test() and exec() methods above both pass in a string that is searched and matched. The difference is that the test() method returns true or false indicating whether the string and the re match, while the exec() method returns an array of matching results. Return only a null value.

// RegExp#test()

var regex = /hello/;
var result = regex.test('hello world');   // true

// RegExp#exec()

var regex = /hello/;
var result = regex.exec('hello world'); / / /'hello']Copy the code

For the exec() method, if the re contains a capture group, the match will appear in the result array:

Var regex = /he(llo)/; var result = regex.exec('hello world'); / / /'hello'.'llo']Copy the code

During development, test() method is generally used for user input verification, such as email verification, mobile phone number verification, etc., while exec() method is generally used to obtain valuable information from specific content, such as ID and email type from user’s email input, location of the number from mobile phone number, etc.

String dependent methods

These are the two methods in the regular prototype. Now let’s look at what methods are available in the string prototype:

String.prototype.search(regexp);
String.prototype.match(regexp);
String.prototype.split([separator[, limit]]);
String.prototype.replace(regexp|substr, newSubStr|function);Copy the code

Let’s start with the String#search() method, which searches the string for matches based on the re argument and returns the index of the first match if it succeeds, or -1 if it fails.

// String#search()

'hello world'.search(/hello/); / / 0'hello world'.search(/hi/);       // -1Copy the code

The String#match() method is similar to the RegExp#exec() method in that it returns an array of results, except that if String#match() has the global flag g in its re argument, only the matched substrings appear in the result and the capture group is ignored. This is somewhat different from RegExp#exec(). Look at the following code:

// String#match()

'hello hello'.match(/he(llo)/); / / /'hello'.'llo']

// String#match() discards the capture group when it encounters a global G modifier

'hello hello'.match(/he(llo)/g); / / /'hello'.'hello']

// RegExp#exec() still contains the capture group

/he(llo)/g.exec('hello hello'); / / /'hello'.'llo']Copy the code

So, if you want to always return the capture group as a result, use the RegExp#exec() method instead of the String#match() method.

Next, the String#split() method, which splits the string and returns an array result containing its substrings. The separator and limit arguments are optional. Separator can be specified as either a string or a re, and limit specifies the maximum number of results to return. If separator is omitted, the array result of the method contains only its own source string. If Sparator specifies an empty string, the source string is split character by character; If separator is a non-empty string or regular expression, the method splits the source string in units of this argument. The following code demonstrates the use of this method:

// String#split()

'hello'.split(); / / /"hello"]
'hello'.split(' '); / / /"h"."e"."l"."l"."o"]
'hello'.split(' ', 3); / / /"h"."e"."l"] // Specify a non-empty string varsource = 'hello world';
var result = source.split(' '); / / /"hello"."world"Var result = source.split(/\s/); / / /"hello"."world"]Copy the code

If separtor is a regular expression and the re contains a capture group, the capture group will also appear in the result array:

// String#split() re capture group

var source = 'matchandsplit';

var result = source.split('and'); / / /"match"."split"] var result = source.split(/and/); / / /"match"."split"Var result = source.split(/(and)/); / / /"match"."and"."split"]Copy the code

Finally, the String#replace() method, which performs both find and replace.

From the function signature above, this method takes two arguments: the first argument can be a regular expression or a string, both representing the substring to be matched; The second argument can specify either a string or a function. If you specify a string, the string will replace the matched substring. If you specify a function, the return value of the function will replace the matched substring.

The String#replace() method eventually returns a new, replaced string. Here’s how to use the replace method:

// String#replace()

var source = 'matchandsplitandreplace';

var result = source.replace('and'.The '-');  // "match-splitandreplace"Var result = source.replace(/and/,function() {
  return The '-';
});                                       // "match-splitandreplace"Copy the code

As you can see from the code above, ‘and’ is replaced with ‘-‘, but we also notice that only the first ‘and’ is replaced; the rest is not processed. Here we need to know that the String#replace() method replaces only the first occurrence of the matching string. If we need global replacement, we specify the first argument as a regular expression and append the global g modifier, as follows:

// String#replace() Global replace

var source = 'matchandsplitandreplace';

var result = source.replace(/and/g, The '-'); // "match-split-replace"

var result = source.replace(/and/g, function() {
  return The '-';
});                                       // "match-split-replace"Copy the code

For the second argument, it’s easy to specify a string. Why use a function and then return a value? Take a look at the following example:

// String#replace() Replaces the argument list of the function

var source = 'matchandsplitandreplace';

var result = source.replace(/(a(nd))/g, function(match, p1, p2, offset, string) {
  
  console.group('match:');
  console.log(match, p1, p2, offset, string);
  console.groupEnd();

  return The '-';
});                                       // "match-split-replace"Copy the code

In the above code, the first argument is a regular expression containing two capture groups (and) and (nd), and the second argument specifies an anonymous function with a list of arguments: Match, P1, p2, offset, string correspond to the matched substring, the first capture group, the second capture group, the index of the matched substring in the source string, and the source string respectively. We can call this anonymous function “replacer” or “replacement function” in the parameter list of the replacement function. Match, offset, and string are always present for each match, while the string #replace() method fills in the intermediate capture groups p1, p2, etc., according to the actual match.

Here is the console print after the code runs:

Now, specifying a function is much more powerful than specifying a string, because every match gets this useful information, and we can do something with it, and finally return a value as a new substring to replace. It is therefore recommended to use this method when calling the String#replace() method.

The String#search() and String#match() method signatures are regular objects. If we pass other types of parameters, they are implicitly converted to regular objects. To get the string value, call toString() and then call new RegExp(val) to get the regular object:

// -> String#search(new RegExp(val.toString()))

'123 123'.search(1); / / 0'true false'.search(true); / / 0'123 123'.search('\\s');    // 3

var o = {
  toString: function() {
    return '\\s'; }};'123 123'.search(o);        // 3

// -> String#match(new RegExp(val.toString()))

'123 123'.match(1); / / /"1"]
'true false'.match(true); / / /"true"]

'123 123'.match('\\s'); / / /""]

var o = {
  toString: function() {
    return '1' (23); }};'123 123'.match(o); / / /"123"."23"]Copy the code

The split() and replace() methods do not convert strings into regular expression objects. For other types of values, they simply call their toString() method to convert parameter values to strings, and they do not convert them further into regular objects. You can test this out for yourself.

The above is the basic knowledge and common methods of regular expression. Due to the limitation of space, more content about regular expression will be introduced and explained by the blogger in the next article. Please look forward to it.




Re modifiers, also known as re flags, limit the matching rules of the re and affect the final result of the match. As we mentioned in the previous article, there are several regular modifiers that can be used individually or in combination:

/\w+/g; // global search
/\w+/i; // ignore case
/\w+/m; // multi-line
/\w+/u; // unicode
/\w+/y; // sticky

/\w+/gi;
new RegExp('\\w+'.'gi');Copy the code

The I is easy to understand, as noted above, ignore case or case insensitive.

Here’s a simple example of a regular expression that matches a capital letter with the I modifier:

'Hello World'.match(/hello/i); / / /"Hello"]

/hello/i.exec('Hello World'); / / /"Hello"]Copy the code

Looking at the global match modifier G, here is an example of a global match:

var source = 'hello world hello JS'; source.match(/hello/); / / /"hello"] source.match(/hello/g); / / /"hello"."hello"]Copy the code

As you can see from the code above, there is only one match result for a regular re. If you want to find all matches, you need to add a G modifier to make it a global match pattern.

The global modifier g is also commonly used in conjunction with the multi-line matching modifier M. We modified the above example slightly by adding a newline and changing the re slightly:

var source = 'hello world\nhello JS'; source.match(/^hello.+/g); / / /"hello world"]Copy the code

As you can see, we are trying to match a string that begins with “hello” in multiple lines of text, but only the first match appears. The following “hello JS” does not match, so we need to add the multi-line match modifier M:

var source = 'hello world\nhello JS'; source.match(/^hello.+/gm); / / /"hello world"."hello JS"]Copy the code

Now, all the results match.

Note, however, that the m modifier alone does not work. It must be combined with g, as in the following example, where the m modifier still matches only the first line:

var source = 'hello world\nhello JS'; source.match(/^hello.+/m); / / /"hello world"]Copy the code

Another important condition is that the modifier m only works if the re contains either the start tag “^” or the end tag “$”. Otherwise, g does not need m.

G needs m var only if it matches the start tag ^ or the end tag $source = 'hello world\nhey world'; Source.match (/he.+/g); / / /"hello world"."hey world"Match (/^he.+/g); / / /"hello world"] source.match(/.+world$/g); / / /"hey world"Source.match (/^he.+/gm); / / /"hello world"."hey world"] source.match(/.+world$/gm); / / /"hello world"."hey world"]Copy the code

RegExp#exec() is the equivalent of a String#match() method that matches a string and returns an array of results. How would the exec() method behave for a re with a global modifier? In practice, the RegExp#exec() method has roughly the same rule as String#match() above, except that RegExp#exec() only matches one result at a time, so it takes multiple loop executions to get all of them. Let’s look at the following example:

var regex = /^hello.+/gm;
var source = 'hello world\nhello JS';

regex.exec(source); / / /"hello world"]
regex.exec(source); / / /"hello JS"]Copy the code

As you can see, the exec() method returns an array of results each time it executes the re instance. Since the re contains a combination of the start tag ^ and gm, we need to execute it twice to get the full result, which differs from the String#match() method. In general, we can use the loop structure to call the RegExp#exec() method to get all the results:

var result = null;
while (result = regex.exec(source)) {
  console.log(result);
}
// output:
// ["hello world"] / ["hello JS"]Copy the code

The RegExp#test() method is used to check if a string matches a pattern. If you want to check if a string matches a pattern on multiple lines, you also need a gm combination.

var source = 'hello world\nhey JS';

/^hello.+/.test(source);      // true

/^hey.+/.test(source);        // false
/^hey.+/g.test(source);       // false

/^hey.+/gm.test(source);      // trueCopy the code

According to the result, the re without gm modifier can only detect the match of one row of data. After adding GM, it can detect multiple rows, as long as any row meets the condition, that is, return true.

Last but not least, the String#replace() method. Again, if the re has ^ or $, then the gm combination is needed. The following code demonstrates the multi-line substitution:

var source = 'hello world\nhello JS'; Source.replace (/hello/g,'hey');    // "hey world\nhey JS"Source. Replace (/^hello/g,'hey');   // "hey world\nhello JS"Replace (/^hello/gm,'hey');  // "hey world\nhey JS"Copy the code

Above is the global match G and the multi-line match M. Let’s look at the U modifier.

The U modifier is a new feature in ES6 that enables regular matching of strings in Unicode mode and correctly handles the four-byte UTF-16 character set. Let’s look at an example of why this modifier is needed:

/^.{3}$/.test('Hello.');    // true
/^.{3}$/.test('𠮷 wild home');    // falseCopy the code

The re is used to check if the string is composed of three characters. Because “𠮷 wild home” in the “𠮷” word, careful observation, will find it is not a “good luck” in the “auspicious” word, but it’s a YiXingZi, the word also belong to the Chinese characters, but later is common in Japanese, for such a word, the general regular match to very hard, and in the ES6, we can specify a u modifier, Enable Unicode mode to match Unicode characters greater than \uFFFF. After we add the u modifier, the re matches:

/^.{3}$/u.test('𠮷 wild home');   // trueCopy the code

Similarly, here are two examples:

// The following re contains Unicode characters and corresponding quantifiers /𠮷{3}/.test('𠮷 𠮷 𠮷');     // false/ 𠮷 {3} / u.t est ('𠮷 𠮷 𠮷');    // true// The following re is used to match non-space characters /^\S$/.test('𠮷');         // false
/^\S$/u.test('𠮷');        // trueCopy the code

In addition, ES6 added the curly bracket Unicode notation, as follows:

var a = '\u{20BB7}';       // '𠮷'

/\u{20BB7}/u.test('𠮷');   // trueCopy the code

Be careful with this expression, though, because \u represents the match character u in a regular re, not when Unicode mode is turned on:

// Check if there are 3'u'Character / \ u {3} /. The test ('uuu');      // true// Check for characters'\u{3}'

/\u{3}/u.test('uuu');     // false

/\u{3}/u.test('\u{3}');   // trueCopy the code

From the above results, when Unicode mode is turned on, \u and the quantifier {3} form a Unicode character, so the result is completely different. In practice, pay special attention to this.

After the U modifier, let’s finally talk about the new Y modifier in ES6.

The y modifier is sticky, which indicates that the last matching object must be matched immediately after the last one. That is, in the case of multiple matches, each match must be performed at the starting position and the last match must be performed at the next position after the last match. The y modifier is similar to the global G modifier, but there are some differences. Let’s start with the following example:

var source = 'hello-hello-world';
var re1 = /hello/g;
var re2 = /hello/y;

re1.exec(source); / / /"hello"]
re2.exec(source); / / /"hello"] console.log(re2.lastIndex); // 6 // The new round of matches will be in"-hello-world"In the re1. The exec (source); / / /"hello"]
re2.exec(source);           // nullCopy the code

As you can see, re1 is a G modifier, re2 is a Y modifier, and the first round is the same. Then we get the starting position of the next round from the lastIndex property of the re instance, and we know that the next round will be matched in “-helo-world”. Since it does not start at “hello”, the result is, G still matches successfully, but y fails, and null is returned.

Let’s modify the re a little bit so that on the second match, “hello” is in the starting position so that it matches successfully:

var source = 'hello-hello-world';
var re2 = /hello-/y;

re2.exec(source); / / /"hello-"] console.log(re2.lastIndex); // 6 // Then a new round of matches will be in"hello-world"In the re2. The exec (source); / / /"hello-"]Copy the code

We can also change the index of the starting position of the new match by changing the lastIndex attribute of the re, so that it conforms to the rule of Y.

var source = 'hello-hello-world';
var re2 = /hello/y;

re2.exec(source); / / /"hello"] // alter lastIndex re2.lastindex = 6; re2.exec(source); / / /"hello"]Copy the code

From the above examples, the y modifier requires that the match target must appear at the starting position, which implies the use of the starting tag “^” :

/hello/y.test('-hello');    // false/^hello/.test('-hello');    // falseCopy the code

When y and g occur at the same time, the global matching is limited. In addition to the Regex#exec() method described above, the gy combination also applies to the replace and match methods of String. After the global matching g plus y, the matching pattern is stricter, and the target must appear first in each match:

// String#replace()

'hello-hello-world'.replace(/hello/g, 'hey');     // "hey-hey-world"// The second hello will not be matched and replaced after y is added'hello-hello-world'.replace(/hello/gy, 'hey');    // "hey-hello-world"// We need to change it to the following'hello-hello-world'.replace(/hello-/gy, 'hey-');  // "hey-hey-world"


// String#match()

'hello-hello-world'.match(/hello/g); / / /"hello"."hello"]

'hello-hello-world'.match(/hello/gy); / / /"hello"]

'hello-hello-world'.match(/hello-/gy); / / /"hello-"."hello-"]Copy the code

That’s all for regular modifiers. Stay tuned for metacharacters and advanced matching in the next post.



In the last two articles, I’ve covered regular methods and regular modifiers in JavaScript. Today I’m going to talk about metacharacters and advanced matching.

First, metacharacters, presumably we are familiar with, JS metacharacters have the following:

/ \ |. * +? ^ $() [] {}Copy the code

They all have special meanings, and we’ll take a look at each of them.

/ (slash)

A regular expression for creating a literal:

var re = /abc/;Copy the code

\ (backslash)

The metacharacters are used to escape other characters, which we call escape characters. The metacharacters listed above, because they have special meanings, need to escape characters to match the metacharacters themselves. For example, to match a slash /, we need to look like this:

/\//.test('a/b');Copy the code

| (vertical bar)

With this, we can match any subexpression on either side of the expression. The following example matches the word see or sea:

/see|sea/.test('see');  // true

/see|sea/.test('see');  // trueCopy the code

. (dot)

Matches any character except newline. We can use it to match almost any letter or character except \ R (\u000D carriage return) and \ N (\u000A new line), as shown in the following example:

/./.test('w');      // true
/./.test('$');      // true

/./.test('\r');     // false
/./.test('\n');     // falseCopy the code

Note that if a Unicode character with a code point greater than 0xFFFF is encountered, it will not be recognized and the u modifier must be added:

/^.$/.test('𠮷');   // false
/^.$/u.test('𠮷');  // trueCopy the code

* (asterisk)

Matches 0 to more subexpressions, that is, subexpressions can be more or less optional. If we add an asterisk to the end of a single character, it is used only as a quantifier for that character, and the final match is context-dependent, as in the following example:

/lo*/.test('hell');     // true
/lo*/.test('hello');    // true
/lo*/.test('hellooo');  // true

/lo*/.test('hey yo');   // false
/yo*/.test('hey yo');   // trueCopy the code

+ (plus)

Matches 1 to more subexpression, that is, the subexpression must exist at least once in a row. If we use the above example again, the result will be different:

/lo+/.test('hell');     // false
/lo+/.test('hello');    // true
/lo+/.test('hellooo');  // trueCopy the code

? (question mark)

Matches 0 to 1 subexpression, that is, subexpression either does not exist or must occur once, not more than once in a row. Let’s change the above example slightly:

/lo? $/.test('hell');     // true/lo? $/.test('hello');    // true/lo? $/.test('hellooo');  // falseCopy the code

^ (caret) & $ (dollar)

These two metacharacters qualify the start and end, respectively, as we used in the above example. Here’s another simple example:

/^hello/.test('hello');   // true
/world$/.test('world');   // true

/^hello/.test('hey yo');  // false
/world$/.test('word');    // falseCopy the code

When you first encountered these metacharacters, you probably wrote a program to remove extra Spaces before and after strings:

var source = ' hello world ';

var result = source.replace(/^\s+|\s+$/g, ' ');

console.log(result);

// output:
// "hello world"Copy the code

( ) open parenthesis & close parenthesis

Used to declare a capture group, the subexpression in parentheses will be matched and remembered as the contents of the capture group, and they will appear in the result array from index 1:

/hel(lo)/.exec('hello'); / / /"hello"."lo"]

/he(l(lo))/.exec('hello'); / / /"hello"."llo"."lo"]Copy the code

[ ] open bracket & close bracket

Used to declare a set of characters to match a character, which can be any character in the set.

/[abc]/.test('b');    // trueCopy the code

Hyphen (hyphen) : hyphen (hyphen) hyphen (hyphen) (hyphen)

/[a-c]/.test('b');    // trueCopy the code

If – appears at the beginning and end of the collection, it no longer represents a range, but matches an actual character, as follows:

/ [-a]/.exec('-abc'); / / /"-"]
/[c-]/.exec('-abc'); / / /"-"]Copy the code

From the above example, we can also see that the characters in the collection are matched first in order. In addition, multiple ranges can also appear at the same time, making the whole set have a larger matching range:

/[A-Za-z0-9_-]/.exec('hello'); / / /"h"]Copy the code

Where “a-za-z0-9_” can be represented by “\w”, so the following example has the same effect as above:

/[\w-]/.exec('hello'); / / /"h"]Copy the code

Finally, remember ^, which in normal expressions represents the start flag, but if it appears at the start of [], it will indicate a negation, indicating that it will not match any character in the set, but any character other than the set character:

/[^abc]/.test('b');   // false

/[^a-c]/.test('b');   // false

/[^a-c]/.test('d');   // trueCopy the code

{ } open brace & close brace

X {n}, x{n,}, x{n,m}, x{n,m}

Var re = /hello{3}$/; re.test('hello');     // false

re.test('hellooo');   // trueVar re = /hello{1,}$/; re.test('hell');      // false

re.test('hello');     // true

re.test('hellooo');   // trueVar re = /hello{1,3}$/; var re = /hello{1,3}$/; re.test('hello');     // true

re.test('helloo');     // true

re.test('hellooo');   // true

re.test('hell');      // false

re.test('hellooooo'); // falseCopy the code

In addition, the *, +,? , they all have a corresponding notation:

* 0 to multiple equals {0,}

+ 1 to multiple equals {1,}

? 0 or 1 is equal to {0,1}

Having said the above metacharacters, let’s take a look at some commonly used escape characters:

Let’s leave the metacharacters here and talk about regular advanced matching.

Capture group reference

As we have seen above, (x) is a capture group, x is a subexpression of the capture group, and the matched capture group will appear in the result array from index 1. For these matched capture groups, we can use $1… $n said.

// The $1.$nVar re = /he(ll(o))/; re.exec('helloworld'); / / /"hello"."llo"."o"] / /"llo"   ->   The $1
// "o"     ->   $2Copy the code

In the String#replace() method, we can simply use a variable like $n:

/ / in the String#replace() references the matched capture group

var re = /(are)\s(you)/;
var source = 'are you ok';

var result = source.replace(re, '$2 $1');

console.log(result);

// output:
// "you are ok"Copy the code

$1 = “are”; $2 = “you”;

In re, we can also use \1… A subexpression such as \n to represent the previously matched capture group is called a backreference. \1 refers to the first previously matched capture group, \2 refers to the second, and so on. Here is an example we use to match the contents of a pair of p tags:

var re = /<(p)>.+<\/\1>/;

re.exec('<div><p>hello</p></div>'); / / /"<p>hello</p>"."p"]Copy the code

As you can see from the result set, we successfully matched all the contents of the P tag, and the element with index 1 in the result set is the content of the capture group match.

Non capturing group

A non-capture group can also be understood as a non-memorizing capture group that matches the content but does not remember the result of the match, that is, the matched content does not appear in the result set.

(we use? The form :x) represents a non-capturing group. The following example illustrates the difference between capturing and non-capturing groups:

Var re = /he(llo)/; re.exec('hello'); / / /"hello"."llo"] // Use (? : llo)"llo"Matches but does not appear in the result set var re = /he(? :llo)/; re.exec('hello'); / / /"hello"]Copy the code

The inertia model

We mentioned several expressions in the metacharacters section above, for example:

x* x+ x? x{n} x{n,} x{n,m}

They default to greedy mode, which is to match as much content as possible. For example, in the following example, we want to match the first HTML tag, and since the default is greedy mode, it will match the entire string:

var re = /<.*>/;

re.exec('<p>hello</p>'); / / /"<p>hello</p>"]Copy the code

That’s not what we want, so what do we do?

We need to append a question mark to these expressions to indicate lazy mode, so that the re matches as little as possible, and the above expressions will look like this:

x*? x+? x?? x{n}? x{n,}? x{n,m}?

To tweak the above example a bit, let’s see what happens:

var re = /<.*? > /; re.exec('<p>hello</p>'); / / /"<p>"]Copy the code

assertions

The so-called assertion is that a certain rule will be matched before or after the specified subexpression. Only when the rule is matched, the subexpression will be matched successfully. The assertion itself is not matched into the result array.

The JavaScript language supports two kinds of assertions:

Zero-width positive prediction prior assertion, expressed as x(? =y), which asserts that x will be followed by y, and only then will x match.

Zero-width negative predictive advance assertion, expressed as x(? ! Y), which asserts that x is not followed by y and matches x only if this condition is met.

The following example demonstrates assertions where the two conditions are opposite:

Var re = /hello(? =world)/; re.exec('helloworld'); / / /"hello"]

re.exec('hellojavascript'); Hello var re = /hello(? ! world)/; re.exec('helloworld');        // null

re.exec('hellojavascript'); / / /"hello"]Copy the code

In the assertion section, we can also use a more expressive condition:

var re = /hello(? =world|javascript)/; re.exec('helloworld'); / / /"hello"]

re.exec('hellojavascript'); / / /"hello"] var re = /hello(? =\d{3,})/; re.exec('hello33world');      // null

re.exec('hello333world'); / / /"hello"]Copy the code

So that’s the assertion part. The content of regular expressions is here, before and after a total of three articles, covering most of the content of JavaScript regular expression, I hope to be helpful to students.