Learn the regular expression of half a year, also can not say always learn it, is and it has been dealing with, how to use regular expression to solve their own problems, and also to consider how to match a large number of text to optimize it. Slowly feel that the regular has become a skill of their own, gradually from a regular expression of small white into a pseudo-proficient.
New REGEXP and//Regular object creation differences
If you've ever written to a python classmate, you'll know that Python can have a lowercase r in front of the string to prevent escaping. Preventing escaping means that str = R ' \ t ' is equivalent to str = ' \\t ', and adding r will prevent \ being escaped.
Why introduce this, because this is the difference between the new REGEXP and//, because we know that the escape character \w\s\d is used frequently in regular expressions, but they are stored in memory in \\w\\s\\d, see an example:
Recommended notation var regex1 =/\w+/g;regex1///\w+/g//regexp notation var regex2 = new RegExp (' \\w+ ', ' G '); regex2///\w+/g//error notation var regex3 = new RegExp (' \w+ ', ' G '); regex3///w+/g
You can also see that the wrong way to only match wwwww such a string, once I have seen someone confuse them, and said the first third one no difference. The output of the second method, or/\w+/g, in the middle or to convert, so recommend the first one.
Of course, there are more wonderful:
var regex4 = new RegExp (/\w+/g); regex4///\w+/g
I, G, M modifier
These modifiers are for JS only, like in Python and re. S indicates. can match line breaks.
For I, ignoring the letter case, is not very common, because it has a lot of alternatives, such as:/[a-za-z]/can be used to replace the/[a-z]/i, as for the two long text processing time efficiency, I have not studied, not conclusive.
I need to note that I will ignore the case of each letter of the regular expression, when we need some words, we can think about/(?: t| T) He boy/.
G is a global match, in the impression that many people may feel that the global match is when the match is used, all the text that matches the regular expression is all matched, this use is very wide, but g there are other more interesting uses, that is the LastIndex parameter.
var str = ' 1a2b3c4d5e6f ', reg =/\d\w\d/g;str.match (reg),//["1a2", "3c4", "5e6"]
Why not include the 2B3,4D5, because the regular expression matches the time, will use the LastIndex to mark the last match position, under normal circumstances, has already matched the content is not participates in the next match. With the G modifier, you can specify where to start the search by using the LastIndex property of the regular object, which is limited to the function exec and test (replace has not studied, has not heard of control Lastindex,match return is an array, unable to control Lastin DEX), modify the following for this topic:
var str = ' 1a2b3c4d5e6f ', reg =/\d\w\d/g;var A;var arr = [];while (a = reg.exec (str)) { Arr.push (a[0]); Reg.lastindex-= 1;} Arr//["1a2", "2b3", "3c4", "4d5", "5e6"]
M is a multi-line match, I found a lot of people introduced m are just a row skip, actually about M is still very interesting. First, to understand the single-line pattern, we know the JavaScript in the regular expression. is unable to match \ r \ n (newline, different systems use different), like Python provides re. S indicates. Can match any character, including \ r \ n, in JS if you want to indicate a match for any character, you can only use [\s\s] this crappy way (and more crappy [\d\d],[.\s]). This mode is called to turn on or off the single-line mode, but JS can not control.
Multi-line mode is related to ^ $ two brothers, if your regular expression is not ^$, it is useless to start the multiline mode immediately. Normal understanding/^123$/can only match string 123, while opening multiline mode/^123$/g can match [' 123 ', ' \n123 ', ' 123\n ', ' \n123\n '], relative to ^$ can match \ r \ n.
var str = ' \na ';/^a/.test (str); False/^a/m.test (str); True
Some people say, M useless. In fact, in some special format, you know that you want to match the content will be immediately after \ r \ n or to the end, this time m is very useful, such as the HTTP protocol requests and responses, are divided by \ r \ n Each line, the response head and response body is divided by \r\n\r\n, we need to match the internal Capacity is at the beginning, through multi-line matching, can obviously improve the matching efficiency.
The original rational thing, we still need to know, in case later will use.
(?:) and (? =) Difference
In regular expressions, parentheses are not used indiscriminately, because parentheses represent groupings, and in the final match results are counted in the word match, and (?:) is to solve the problem, its alias is called the non-capturing grouping.
var str = ' Hello world! '; var regex =/hello (\w+)/;regex.exec (str); ["Hello World", "world"]var regex2 =/hello (?: \ w+)/;regex2.exec (str); ["Hello World"]
You can see (?:) does not count the bracketed content into sub-groupings.
Beginners can be difficult to understand about (? =), especially some very nice pre-Cha Zheng expressions. In fact, there is a (?!), but it and (? =) belong to a class, called positive positive (negative) pre-check, it also has many aliases such as 0-width positive lookahead assertion. But I think the most important just remember this two points, pre-check and non-capture.
The pre-check means that on the basis of the previous matching success, check backwards to see if the content is in line with the pre-check. Because it is a pre-check, LastIndex does not change and is not captured in the total score group, and is not captured in subgroups.
var str = ' Hello world! '; var regex =/hello (? =\w+)/;regex.exec (str); ["Hello"]//replace also same as var regex2 =/(?: AB) (CD)/' ABCD '. Replace (REGEX2, ' $ ')//"CD"
and (?:) difference is: I'm accustomed to the total result of the match is called the overall group, the match function returns the array each item is a total score group, the first item in the return array of the EXEC function is the total score group. (?:) will put the bracketed content into the total score group, (? =) will not be included in the parentheses in the total score group.
Plainly, the powerful lastIndex is in effect. (?:) and (? =) The difference is there, when using the appropriate trade-offs.
Say so much about the (? =) content, the next step to order it! Now the demand is a string of money "10000000", but in the internationalization of the expression method, there should be a comma "10,000,000" in the three-bit, give you a string without commas, replaced with a comma.
var str = "10000000"; var regex =/\d (? = (\d{3}) +$)/g;str.replace (regex, ' $&, '); "10,000,000"
We analyze the regex,/\d (? = (\d{3}) +$)/g It is global g, in fact it matches only one \d, (? = (\d{3}) +$) is pre-sentenced content, previously said that the content of the pre-judgment does not count to match the results, LastIndex or stay in the location of \d. (? = (\d{3}) +$) to the end there is at least a group of 3 together numbers, only to calculate the success of the pre-award.
\d = 1, do not meet the pre-judgment, backward one bit, \d = 0, to meet the pre-judgment, replace.
(?!) Forward judgment
(? =) and (?!) are called forward-looking, but often the positive word binds our minds. The positive feeling is that it can only be pre-judged after the regular expression, so why can't the pre-judgment be put forward? The following example is also very interesting.
Verification of a simple password, to ensure that it contains at least two of the uppercase letters, lowercase letters, numbers, and the length 8~20.
If you can write more than one regular, this topic is very simple, the idea is:/^[a-za-z\d]{8,20}$/&&! (/[a-z]+/) &&! (/[a-z]+/) &&! (/\d+/), look at the eyes are spent, a good long string.
Below with (?!) forward-looking judgments to achieve:
var regex =/^ (?! [a-z]+$) (?! [a-z]+$) (?! \d+$) [A-za-z\d]{8,12}$/;regex.test (' 12345678 '); Falseregex.test (' 1234567a '); True
Analysis, because like (?!) pre-judgment does not consume lastIndex, can be placed in front of the forward-looking. (?! [a-z]+$] means that from the current lastIndex (that is ^) start all the way to $, not all lowercase letters, (?!). [a-z]+$] cannot be all capitals, (?! \d+$) can not be all numbers, [a-za-z\d]{8,12}$ This is the main body, when judging here, lastIndex position is still 0, this is (?!) the efficiency of the forward-looking.
The problem of non-greed and greed
Greed appears in + * {1,} such an indeterminate number of matches, so-called greed, which means that regular expressions are matched as much as possible to match the content of the condition. For example/hello.*world/match ' Hello World,nice World ' will match to the end of the second world.
In view of the above situation, can be used? To implement a non-greedy match.? There are many uses in regular expressions, under normal circumstances, it means that the preceding character matches 0 or 1 times, that is, the simplified version of {0,1}, if it appears after some indeterminate number of qualifiers, represents a non-greedy match. The result of/hello.*?world/matching ' Hello World,nice world ' is Hello world.
When I first began to write the regular, I wrote the regular is greedy mode, often get the results and expected some deviation, is because less? The reason.
When I first entered the regular, the non-greedy mode gave me an illusion. Or the previous example, the matching content for a change, with/hello.*?world/match ' Hello Word,nice world ', because word is not equal to world, after the first attempt to match the failure, should return the failure, but the result is successful, return is ' Hello Word,nice world '.
At first I did not understand the situation, but to think about it is right, it should have returned to success. As for how the match failed after the first attempt, the match will no longer continue, only through optimization. *. If we take the. *?end in this way,. * Will swallow all the characters, slowly spit out the last few characters, and end comparison, if it is greedy, spit to the first to meet the conditions of the stop, if not greedy, always spit until you can not spit, the results from their recent return.
So, greed is returning the most recent successful match, not the first attempt.
Avoid runaway backtracking
Backtracking can kill a regular expression, which is not false. The regular expression backtracking is also very well understood, that is, the regular engine found that the two way to go, it will choose one of them, the other way to save the time to use.
For example, the regular/ab?c/after a successful match to a, there can be B, or no B, this time to provide two options. There are other types of backtracking, such as/to (Night|do)/. Of course, the impact of performance of the backtracking will be and. *. +. {m} related.
The so-called backtracking runaway, is the choice of path too much, see a common backtracking runaway example, regular/(a+a+) +b/, if the match is successful, will return quickly, then the match failed, very scary. For example, to match 10 a aaaaaaaaaa, assuming the first A + swallowed 9 A, the entire regular spit last character found not B, know spit, can not return false, the first A + swallow 8 A, .... The complexity of the backtracking times is the square of N.
Of course you might say that you don't write such silly regular expressions. Are you sure? Let's look at a regular expression that matches the HTML tag,/[\s\s]*? [\s\s]*? [\s\s]*? [\s\s]*? [\s\s]*? (It feels silly to write like that). If everything is OK, match a normal HTML page and work well. But what if not at the end, every [\s\s]*? Expands its scope, one at a time, to find a string that satisfies.
When it comes to backtracking, sometimes it's time to think about it. * {} Query collection question, anyway my advice is to try to avoid using any character matching [\s\s], which is really a bit too violent. Because we write the regular time, are in the correct matching ideas to write, but also need to consider if the match is not successful, how to let [a-za-z]* set as soon as possible to stop, such as [^\r\n]* in matching a single row when the effect is good, the instant match failure can quickly stop.
Summarize
I feel this article is very messy, east of the West, probably I have learned in the past few months of the regular expression of knowledge is written here, of course, this does not include some basic knowledge. I think learning is the most important or to practice, only in the actual project summed up in the regular experience, just calculate what you are mastering, if only a simple less eye, time long, will eventually forget. Share!
Reference
RegExp Object-Nanyi
MSDN REGEXP
Advanced Regular Expressions
How to find the file named ". js" file, but to filter out the ". Min.js" file.
The code is as follows:
var regex =/^ (?!. *\.min\.js$). +\.js$/;regex.test (' a.js '); Trueregex.test (' b.min.js '); Falseregex.test (' c.css '); False