Problem: There is a string: "Python php ruby JavaScript jsonp perhapsphpisoutdated"
For this string, use pure to get all words with P but not ph
Output array [' Python ', ' javascript ', ' Jsonp ']
This question has been thought for a long time and has no idea.
My solution is to
var result = str.match(/\b\w*(?=p)\w*\b/g) .filter((value)=>!/.*(?=ph)/.test(value))var result2 = str.match( /\b((?!ph|\s).)*((p[^h\s]((?!ph|\s).)*)|p)\b/g ) console.log(result2)
But it doesn't meet the requirements of pure.
There are Daniel in the group who gave such an answer.
Perfect operation
But I don't understand, I hope Daniel can help me interpret
Reply content:
Problem: There is a string: "Python php ruby JavaScript jsonp perhapsphpisoutdated"
For this string, use pure to get all words with P but not ph
Output array [' Python ', ' javascript ', ' Jsonp ']
This question has been thought for a long time and has no idea.
My solution is to
var result = str.match(/\b\w*(?=p)\w*\b/g) .filter((value)=>!/.*(?=ph)/.test(value))var result2 = str.match( /\b((?!ph|\s).)*((p[^h\s]((?!ph|\s).)*)|p)\b/g ) console.log(result2)
But it doesn't meet the requirements of pure.
There are Daniel in the group who gave such an answer.
Perfect operation
But I don't understand, I hope Daniel can help me interpret
var str = 'python php ruby javascript jsonp perhapsphpisoutdated';var reg = /\b(\w*(p[^h\s](?!ph))\w*)\b/g;str.match(reg);// => ["python", "javascript", "perhapsphpisoutdated"]
\b
is a boundary character, a range of \w
\W
characters between and.
()
The identifier is a sub-expression.
(?!)
Identifying a reverse-antecedent assertion, unlike a subexpression, is an antecedent assertion and is not logged.
[^]
Identifies a collection that does not meet the criteria
So the regular meaning above is to take a "p" between the boundaries, but the string immediately following it is not "H" or "space", and there are no "ph" strings.
\b((?!ph|\s).)*((p[^h\s]((?!ph|\s).)*)|p)\b/g
\b
is a boundary character
So the corresponding match for each word is:
((?!ph|\s).)*((p[^h\s]((?!ph|\s).)*)|p)
Split the expression into three parts:
((?!ph|\s).)*
(p[^h\s]((?!ph|\s).)*)
p
Most of the expressions appear in the ((?!ph|\s).)*
analysis.
The JavaScript authoritative guide says: (?!p)
is a 0-width Negative lookahead assertion , indicating that the next character does not p
match
The 0 width here means that it does not occupy a match :
Perhaps this is difficult to understand, for example, for example:
"1234".match(/((?!34).)*/)
the calculated value
Before the first time (?!34)
there was nothing, ignoring, .
matching only, matching to "1"
, string remaining"234"
Match "234"
, test "23"
whether match ?!
in "34"
, result mismatch, continue, "23"
not consumed, next .
match to "2"
,
Match "34"
, due to match "34"
, ?!
"34"
termination of Match
The matching result of the entire expression is"12"
Conclusion: The expression of the /((?!p).)*/
form matches the p
previous part of the string
Here's a look at the previous three expressions:
((?!ph|\s).)*
(p[^h\s]((?!ph|\s).)*)
p
The first expression represents a character that matches "ph"
as long as possible before a word or a space
The second expression matches the characters in "p"
and after the word, the "p"
first character after the request cannot be "h"
, and the same requirement does not match to"ph"
The third expression matches the individual "p"
character, because the shortest match in the previous match is in the form of p[^h\s]
at least two characters, and the individual "P" characters are not included, so the individual matches the requirements of the landlord.
Comb it will find that the above matching three expressions do not match "ph"
, but there will certainly be "p"
, fully conform to the requirements of the main question