preface

Digit thousandth segmentation, 3-3-4 concatenation of mobile phone numbers, trim function implementation, HTML escape, obtaining URL query parameters… Do you often encounter them in interviews and at work? Let’s take a look at how to use re to catch them all!!

1. Digital price split in thousandths

Change 123456789 to 123,456,789

This problem is estimated that we often meet in the interview and work, the frequency is relatively high.

Regular results

'123456789'.replace(/ (? ! (^)? =(\d{3})+$)/g.', ') / / 123456789
Copy the code

Added small quartile support

The analysis process

The question probably means:

  1. Add a comma before every third digit from the back

  2. Do not start with a comma (e.g.,123 does not end with 123)

Does it fit (? What’s the rule of p? P can represent every three digits, and the comma to be added is exactly where (? =p) matched position.

Step one, try to get the first comma out of it


let price = '123456789'
let priceReg = / (? =\d{3}$)/

console.log(price.replace(proceReg, ', ')) // 123456,789
Copy the code

Step two, get all the commas out

To get all the commas out, the main problem is how to represent groups of three numbers, multiples of three. We know that regular brackets can turn a p pattern into a small whole, so using the properties of brackets, we can write it like this


let price = '123456789'
let priceReg = / (? =(\d{3})+$)/g

console.log(price.replace(priceReg, ', ')) / /, 123456789

Copy the code

Step three, remove the first comma,

It is not enough to remove the first comma from the list. Is there a knowledge that fits this scenario? That’s right. ! P), that’s it, the combination of the two is to add a comma before every three digits, but this position cannot be the first.


let price = '123456789'
let priceReg = / (? ! (^)? =(\d{3})+$)/g

console.log(price.replace(priceReg, ', ')) / / 123456789
Copy the code

2. Divide the phone number 3-4-4

Change the phone number 18379836654 to 183-7983-6654

Form collection scenarios are often encountered in mobile phone formatting

Regular results

let mobile = '18379836654' 
let mobileReg = / (? =(\d{4})+$)/g 

console.log(mobile.replace(mobileReg, The '-')) / / 183-7983-6654

Copy the code

The analysis process

With the thousandths of the number above, it would be much easier to do the problem, which is to find the position from back to front:

Every four digits in front of the position, and replace this position with –


let mobile = '18379836654'
let mobileReg = / (? =(\d{4})+$)/g

console.log(mobile.replace(mobileReg, The '-')) / / 183-7983-6654

Copy the code

3. Mobile phone number 3-4-4 is segmented and extended

To change the mobile phone number 18379836654 to 183-7983-6654, the following conditions must be met

  1. 123 = > 123
  2. 1234 = > 123-4
  3. 12345 = > 123-45
  4. 123456 = > 123-456
  5. 1234567 = > 123-4567
  6. 12345678 = > 123-4567-8
  7. 123456789 = > 123-4567-89
  8. 12345678911 = > 123-4567-8911

Think of this as something we often encounter in the process of users entering mobile phone numbers, which need to be constantly formatted.

Regular results


const formatMobile = (mobile) = > {
  return String(mobile).slice(0.11)
      .replace(/ (? <=\d{3})\d+/.($0) = > The '-' + $0)
      .replace(/ (? < = [-] \ d \ d {1, 4} {8}) /.($0) = > The '-' + $0)}console.log(formatMobile(18379836654))

Copy the code

The analysis process

(this use? =p) is not suitable, for example, 1234 would become -1234. We need to find another way, is there anything else in regex that can handle this scenario? There are (? <=p)

The first step is to get the first – out

const formatMobile = (mobile) = > {
  return String(mobile).replace(/ (? <=\d{3})\d+/.The '-')}console.log(formatMobile(123)) / / 123
console.log(formatMobile(1234)) / / 123-4

Copy the code

Let’s get the second – out

Then we came up with the second one, the second one – right at number 8 (1234567-).

const formatMobile = (mobile) = > {
  return String(mobile).slice(0.11)
      .replace(/ (? <=\d{3})\d+/.($0) = > The '-' + $0)
      .replace(/ (? < = [-] \ d \ d {1, 4} {8}) /.($0) = > The '-' + $0)}console.log(formatMobile(123)) / / 123
console.log(formatMobile(1234)) / / 123-4
console.log(formatMobile(12345)) / / 123-45
console.log(formatMobile(123456)) / / 123-456
console.log(formatMobile(1234567)) / / 123-4567
console.log(formatMobile(12345678)) / / 123-4567-8
console.log(formatMobile(123456789)) / / 123-4567-89
console.log(formatMobile(12345678911)) / / 123-4567-8911

Copy the code

4. Verify the validity of the password

The password contains 6 to 12 characters, including digits, lowercase letters, and uppercase letters, but must contain at least two types of characters

Regular results

let reg = / (((? =.*\d)((? =.*[a-z])|(? =.*[A-Z])))|(? =.*[a-z])(? =. * [a-z])) ^] [A zA - Z \ d {6, 12} $/

console.log(reg.test('123456')) // false
console.log(reg.test('aaaaaa')) // false
console.log(reg.test('AAAAAAA')) // false
console.log(reg.test('1a1a1a')) // true
console.log(reg.test('1A1A1A')) // true
console.log(reg.test('aAaAaA')) // true
console.log(reg.test('1aA1aA1aA')) // true

Copy the code

The analysis process

They’re made up of three conditions

  1. The password contains 6-12 characters

  2. The value consists of digits, lowercase characters, and uppercase letters

  3. Must contain at least two types of characters

The first step is to write conditions 1 and 2 and the re

Let reg = / ^] [a zA - Z \ d {6, 12} $/Copy the code

The second step must contain some character (number, lowercase, uppercase)

let reg = /(? =.*\d)/ / this re means that a position is matched // This position needs to satisfy any number of symbols, followed by a number, // Note that it ends up with a position and not something else // (? Console. log(reg.test('hello')) // false console.log(reg.test('hello1')) // true Console. log(reg.test('hel2lo')) // true // Same for other typesCopy the code

Third, write out the full re

It must contain two types of characters, which can be combined in the following four ways

  1. Combination of numbers and lowercase letters

  2. Combination of numbers and uppercase letters

  3. Combination of lowercase and uppercase letters

  4. Combination of numbers, lowercase letters, and uppercase letters (but the first three already cover the fourth)

// let reg = /((? =.*\d)((? =.*[a-z])|(? =.*[a-z]))); // let reg = /(? =.*[a-z])(? =.*[a-z])/ / let reg = /((? =.*\d)((? =.*[a-z])|(? =.*[A-Z])))|(? =.*[a-z])(? =.*[a-z])/ / let reg = /((? =.*\d)((? =.*[a-z])|(? =.*[A-Z])))|(? =.*[a-z])(? =. * [a-z])) ^] [A zA - Z \ d {6, 12} $/ console log (reg. Test (' 123456 ')) / / false console. The log (reg. Test (" aaaaaa ")) / / false console.log(reg.test('AAAAAAA')) // false console.log(reg.test('1a1a1a')) // true console.log(reg.test('1A1A1A')) // true console.log(reg.test('aAaAaA')) // true console.log(reg.test('1aA1aA1aA')) // trueCopy the code

5. Extract consecutive and repeated characters

Extract duplicate characters, for example 12323454545666, extract [’23’, ’45’, ‘6’]

Regular results

const collectRepeatStr = (str) = > {
  let repeatStrs = []
  const repeatRe = /(.+)\1+/g
  
  str.replace(repeatRe, ($0, $1) = >{$1 && repeatStrs.push($1)})return repeatStrs
}

Copy the code

The analysis process

There are several key messages in the question

  1. Consecutive repeated characters
  2. There is no limit to the length of consecutive repeated characters (e.g. 23, 45 are two digits, and 6 is one digit)

So what is continuous repetition?

11 is a continuous repeat, 22 is a continuous repeat, 111 is certainly a continuous repeat. That is, some character X must be followed by X, which is called continuous repetition. If we know that X is exactly 1, then PI over 11 plus PI over 1 would match, but the point is that we don’t know what X is here, so what do we do? .

This problem can be easily solved by using the re knowledge of backreferences.

The first step is to write out a re that represents a single character repetition

// X is available here. All the characters are referenced in parentheses, followed by the reverse application \1, which reflects the meaning of continuous repetition
let repeatRe = / (.). \ 1 /

console.log(repeatRe.test('11')) // true
console.log(repeatRe.test('22')) // true
console.log(repeatRe.test('333')) // true
console.log(repeatRe.test('123')) // false

Copy the code

Second, write out the re that represents n character repetitions

The quantifier + in parentheses is used to indicate n repeated characters because it is not certain whether to match 11 or 45, 45, and the backreference itself can be more than one, such as 45, 45, 45


let repeatRe = / (+) \ + / 1

console.log(repeatRe.test('11')) // true
console.log(repeatRe.test('22')) // true
console.log(repeatRe.test('333')) // true
console.log(repeatRe.test('454545')) // true
console.log(repeatRe.test('124')) // false

Copy the code

The third step is to extract all consecutively repeated characters


const collectRepeatStr = (str) = > {
  let repeatStrs = []
  const repeatRe = /(.+)\1+/g
  // Most of the time replace is not used for replacement, but for data extraction
  str.replace(repeatRe, ($0, $1) = >{$1 && repeatStrs.push($1)})return repeatStrs
}


console.log(collectRepeatStr('11')) / / / "1"
console.log(collectRepeatStr('12323')) / / / "23"
console.log(collectRepeatStr('12323454545666')) / / / "23", "45", "6"]

Copy the code

6. Implement a trim function

Removes leading and trailing whitespace from a string

Regular results

/ / remove the blank space method const trim = (STR) = > {return STR. Replace (/ ^ | \ \ s * * $s/g, "')} / / extraction method of the space const trim = (STR) = > {return STR. Replace (/ ^ \ s * (. *?) \s*$/g, '$1') }Copy the code

The analysis process

When we first look at the problem, the first thing that comes to our mind is to delete the blank part and keep the non-blank part, but we can also go another way, we can also extract the non-blank part, regardless of the blank part. Next we write the two trim method implementations

Method one, remove the space method


const trim = (str) = > {
  return str.replace(/^\s*|\s*$/g.' ')}console.log(trim('Front End Bighead')) // Front end bighead fish
console.log(trim('Front End Bighead')) // Front end bighead fish
console.log(trim('Front End Bighead')) // Front end bighead fish
console.log(trim('Front End Bighead')) // Front end bighead fish

Copy the code

Method two, extract non – space method


const trim = (str) = > {
  return str.replace(/^\s*(.*?) \s*$/g.'$1')}console.log(trim('Front End Bighead')) // Front end bighead fish
console.log(trim('Front End Bighead')) // Front end bighead fish
console.log(trim('Front End Bighead')) // Front end bighead fish
console.log(trim('Front End Bighead')) // Front end bighead fish

Copy the code

7. HTML escaped

One way to prevent XSS attacks is to do HTML escape. The escape rules are as follows, requiring the corresponding characters to be converted into equivalent entities. In reverse escape, the escaped entity is converted to the corresponding character

character Escaped entities
& &amp;
< &lt;
> &gt;
" &quot;
' &#x27;

Regular results


const escape = (string) = > {
  const escapeMaps = {
    '&': 'amp'.'<': 'lt'.'>': 'gt'.'"': 'quot'."'": '# 39'
  }
  const escapeRegexp = new RegExp(` [The ${Object.keys(escapeMaps).join(' ')}] `.'g')

  return string.replace(escapeRegexp, (match) = > ` &${escapeMaps[match]}; `)}Copy the code

The analysis process

Global match &, <, >, “, ‘, just replace it with the table above. When a character can be one of many things, we usually use groups of characters: [&<>”‘]

const escape = (string) = > {
  const escapeMaps = {
    '&': 'amp'.'<': 'lt'.'>': 'gt'.'"': 'quot'."'": '# 39'
  }
  // This has the same effect as /[&<>"']/g
  const escapeRegexp = new RegExp(` [The ${Object.keys(escapeMaps).join(' ')}] `.'g')

  return string.replace(escapeRegexp, (match) = > ` &${escapeMaps[match]}; `)}console.log(escape(` 
      

hello world

`
)) /* < div> < p> hello world< /p> < /div> * / Copy the code

8. HTML reverse escape

Regular results

The reverse escape, which is the reverse process, is easy to write down

const unescape = (string) = > {
  const unescapeMaps = {
    'amp': '&'.'lt': '<'.'gt': '>'.'quot': '"'.'# 39': "'"
  }

  const unescapeRegexp = / & ([^;] +); /g

  return string.replace(unescapeRegexp, (match, unescapeKey) = > {
    return unescapeMaps[ unescapeKey ] || match
  })
}


console.log(unescape(` < div> < p> hello world< /p> < /div> `))

/* 
      

hello world

*/
Copy the code

9. Hump strings

As follows, change the corresponding string to hump

1. foo Bar => fooBar

2. foo-bar---- => fooBar

3. foo_bar__ => fooBar

Copy the code

Regular results

const camelCase = (string) = > {
  const camelCaseRegex = /[-_\s]+(.) ? /g

  return string.replace(camelCaseRegex, (match, char) = > {
    return char ? char.toUpperCase() : ' '})}Copy the code

The analysis process

Analyze the pattern of the problem

  1. It comes before every wordZero or more- The blank space _Such as,Foo,--foo,__FOO,_BAR, Bar)
  2. - The blank space _It may not be followed by anything like (__,--)
const camelCase = (string) = > {
  / / note (.). ? Here? It's in order to satisfy condition two
  const camelCaseRegex = /[-_\s]+(.) ? /g

  return string.replace(camelCaseRegex, (match, char) = > {
    return char ? char.toUpperCase() : ' '})}console.log(camelCase('foo Bar')) // fooBar
console.log(camelCase('foo-bar--')) // fooBar
console.log(camelCase('foo_bar__')) // fooBar

Copy the code

10. Convert the first letter of the string to uppercase and the rest to lowercase

For example, hello World becomes Hello World

Regular results


const capitalize = (string) = > {
  const capitalizeRegex = / (? :^|\s+)\w/g

  return string.toLowerCase().replace(capitalizeRegex, (match) = > match.toUpperCase())
}

Copy the code

The analysis process

Find the first letter of the word and convert it to a capital letter. The word may be preceded by a beginning or multiple Spaces.


const capitalize = (string) = > {
  const capitalizeRegex = / (? :^|\s+)\w/g

  return string.toLowerCase().replace(capitalizeRegex, (match) = > match.toUpperCase())
}

console.log(capitalize('hello world')) // Hello World
console.log(capitalize('hello WORLD')) // Hello World

Copy the code

11. Get the image addresses of all the IMG tags in the web page

Requirements must be online links For example, https://xxx.juejin.com/a.jpg, http://xxx.juejin.com/a.jpg, / / xxx.juejjin.com/a.jpg

The analysis process

Those of you who have written some crawlers are familiar with the URL matching the IMG tag. In order to accurately capture the image address of the little sister, you must use all your wits, and finally get it.

And they define that

  1. Image labelimg
  2. Need to be online link form, some base64 images need to filter out

Let’s look directly at the result and see what the re means in visual form


const matchImgs = (sHtml) = > {
  const imgUrlRegex = /
      
       ]+src="((? :https? :)? / / / / / ^ "] +) "[^ >] *? >/gi
      [^>
  let matchImgUrls = []
  
  sHtml.replace(imgUrlRegex, (match, $1) = >{$1 && matchImgUrls.push($1)})return matchImgUrls
}


Copy the code

Let’s break down the re into parts

  1. Everything from the img tag to the SRC tag is fine, as long as it is not >

  2. The part in parentheses, the PART of the URL we want to extract, exists as a capture group for direct retrieval

    2.1 (? :https? :)? The protocol header is HTTP: or HTTPS:

    2.2 Outside of parentheses? , indicating that no protocol header is allowed, that is, links in the form of //xxx.juejjin.com/a.jpg are supported

    2.3 Followed by two slashes

    2.4 Since SRC =”” SRC =”” [^”]+ means anything but”

  3. The img end tag > is used for everything else [^>]*.

Try the results

We go to Zhihu, open the console, we can see that it is in line with expectations.

12. Obtain the URL query parameter by name

Regular results

const getQueryByName = (name) = > {
  const queryNameRegex = new RegExp(`? [&]${name}) = (/ ^ & * (& | $) `)
  const queryNameMatch = window.location.search.match(queryNameRegex)
  // Generally through decodeURIComponent decoding processing
  return queryNameMatch ? decodeURIComponent(queryNameMatch[1) :' '
}

Copy the code

The analysis process

The parameter name= on the URL query may be the position of the front-end bighead fish

  1. Following the question mark? Name = bighead &sex=boy

  2. In the last position? Sex =boy&name= front end bighead fish

  3. Between one and two? Sex =boy&name= bighead &age=100

So you only have to deal with three places and you can basically get it by regex

  1. Name can only be preceded by? Or &
  2. The value of a value can be anything except an ampersand
  3. Value can only be followed by an ampersand or an end position

const getQueryByName = (name) = > {
  const queryNameRegex = new RegExp(`? [&]${name}(= (/ ^ & *)? : & ` | $))
  const queryNameMatch = window.location.search.match(queryNameRegex)
  // Generally through decodeURIComponent decoding processing
  return queryNameMatch ? decodeURIComponent(queryNameMatch[1) :' '
}
// 1
// https://juejin.cn/?name= front end bighead &sex=boy
console.log(getQueryByName('name')) // Front end bighead fish

// 2. Name is at the end
// https://juejin.cn/?sex=boy&name= front-end bighead fish
console.log(getQueryByName('name')) // Front end bighead fish


// 2. Name is in the middle
// https://juejin.cn/?sex=boy&name= bighead &age=100
console.log(getQueryByName('name')) // Front end bighead fish


Copy the code

13. Match the 24-hour system time

Check whether time meets the requirements of the 24-hour system. The matching rule is as follows

  1. 01:14
  2. 1:14
  3. 1:1
  4. 23:59

Regular results

const check24TimeRegexp = / ^ (? : (? : 0? |1)\d|2[0-3]):(? : 0? |[1-5])\d$/

Copy the code

The analysis process

The hours and minutes of the 24-hour system must be met

when

  1. The first one could be 012

  2. The second

    2.1 When the first digit is 01, the second digit can be any digit

    2.2 When the second digit is 2, the second digit can only be 0, 1, 2, or 3

points

  1. The first digit could be 0, 1, 2, 3, 4, 5
  2. The second digit can be any number

The first step is to write out the re that conforms to rules 1 and 4

const check24TimeRegexp = / ^ (? :[01]\d|2[0-3]):[0-5]\d$/

console.log(check24TimeRegexp.test('01:14')) // true
console.log(check24TimeRegexp.test('23:59')) // true
console.log(check24TimeRegexp.test('0' began crying)) // false

console.log(check24TimeRegexp.test('and')) // false requires support
console.log(check24TimeRegexp.test('1')) // false requires support


Copy the code

Step 2: Write both the hour and minute singular

const check24TimeRegexp = / ^ (? : (? : 0? |1)\d|2[0-3]):(? : 0? |[1-5])\d$/

console.log(check24TimeRegexp.test('01:14')) // true
console.log(check24TimeRegexp.test('23:59')) // true
console.log(check24TimeRegexp.test('0' began crying)) // false

console.log(check24TimeRegexp.test('and')) // true
console.log(check24TimeRegexp.test('1')) // true

Copy the code

14. Match the date format

Dd, YYYY/MM/DD, for example, 2021-08-22, 2021.08.22, 2021/08/22 May not consider flat leap years

Regular results

const checkDateRegexp = /^\d{4}([-\.\/])(? : 0 [1-9] | 1\1 ([0-2])? :0[1-9]|[12]\d|3[01])$/
Copy the code

The analysis process

The date format is divided into three main parts

  1. \d{4}

  2. Mm Month section

    2.1 There are only 12 months in a year, 0\ D can be used in the first 10 months

    2.2 October and thereafter 1[0-2]

  3. The dd part,

    3.1 The maximum number of days per month is 31

    3.2 The minimum is no. 1

The separator

It is important to note that the separators must be the same and cannot be mixed with all three, such as 2021.08-22

Based on the above analysis we can write

const checkDateRegexp = /^\d{4}([-\.\/])(? : 0 [1-9] | 1\1 ([0-2])? :0[1-9]|[12]\d|3[01])$/

console.log(checkDateRegexp.test('2021-08-22')) // true
console.log(checkDateRegexp.test('2021/08/22')) // true
console.log(checkDateRegexp.test('2021.08.22')) // true
console.log(checkDateRegexp.test('2021.08/22')) // false
console.log(checkDateRegexp.test('2021/08-22')) // false

Copy the code

The visual form has a Backref #1, which backreferences the first grouping ([-\.\/]), ensuring that the dividers are the same

15. Match hexadecimal color values

Ask to match hexadecimal color values like #ffbbad and # ffffrom the string string

Regular results

const matchColorRegex = / #? :[\da-fA-F]{6}|[\da-fA-F]{3})/g

Copy the code

The analysis process

The hexadecimal color value consists of the following two parts

  1. #
  2. Six or threedigital,Uppercase lettercomposition

const matchColorRegex = / #? :[\da-fA-F]{6}|[\da-fA-F]{3})/g
const colorString = '#12f3a1 #ffBabd #FFF #123 #586'

console.log(colorString.match(matchColorRegex))
// [ '#12f3a1', '#ffBabd', '#FFF', '#123', '#586' ]

Copy the code

We can’t write re as /#(? : [\ da – fA – F] {3} | [\ da – fA – F] {6})/g, because the regular of multiple branch | is inert match, first match in front of the branch, At this time to match ‘# # # 12 f3a1 ffBabd FFF # 123 # 586’, will be [‘ # 12 f ‘, ‘# ffB’, ‘# FFF’, ‘# 123’, ‘# 586]

16. Check URL prefixes

Check whether a URL is HTTP or HTTPS

This one is relatively simple, but it is often encountered in daily work.

Regular results


const checkProtocol = /^https? : /

console.log(checkProtocol.test('https://juejin.cn/')) // true
console.log(checkProtocol.test('http://juejin.cn/')) // true
console.log(checkProtocol.test('//juejin.cn/')) // false

Copy the code

17. Test Chinese

Check whether the string STR is composed of all Chinese characters

The most important thing is to determine the unicode encoding range of Chinese characters. If you want to add a match beyond the basic Chinese characters, you only need to use multiple selection branches

The analysis process



const checkChineseRegex = /^[\u4E00-\u9FA5]+$/

console.log(checkChineseRegex.test('Front End Bighead'))
console.log(checkChineseRegex.test('1 Head Bighead '))
console.log(checkChineseRegex.test('Bighead Head 2'))


Copy the code

18. Match cell phone numbers

Checks if a string matches the rule for a mobile phone number

timeliness

The mobile phone number itself is timeliness, and major operators sometimes launch new numbers, so our re is also timeliness and needs to be supplemented in time

regularity

You can check the mobile terminal communication numbers in Mainland China for specific rules

The parsing process

Since the ChinaMobilePhoneNumberRegex regular reference


const mobileRegex = / ^ (? : \ +? 86)? 1 (? :3\d{3}|5[^4\D]\d{2}|8\d{3}|7(? :[235-8]\d{2}|4(? :0\d|1[0-2]|9\d))|9[0-35-9]\d{2}|66\d{2})\d{6}$/

console.log(mobileRegex.test('18379867725'))
console.log(mobileRegex.test('123456789101'))
console.log(mobileRegex.test('+ 8618379867725'))
console.log(mobileRegex.test('8618379867725'))

Copy the code

What’s a good way to make sense of a long and seemingly complex re?

Visual tools can help us break down the re.

So mobileRegex can be broken down into the following sections

  1. (? : \ +? 86)?: Mobile phone prefix, pass in parentheses? :Identifies non-reference groups
  2. 1: All mobile phone numbers start with 1
  3. (a|b|c|…) : all kinds of situation of 2 ~ 5, through the multiple branch | explain them one by one
  4. \ D {6}: 6 arbitrary digits

After disassembling, we will find that it is not complicated, but in the third part, because there are too many possibilities, we use many branches to explain. As long as we make clear the rules of mobile phone number, it is not difficult to find the rules of each group.

19. Add Spaces before and after English words

A string of alphanumeric characters with regular Spaces before and after English words.

You say come, go is go => You say come, go is go

The parsing process

Here you only need to understand the concept of the position \b in re, which means the boundary of a word. Specifically, there are three rules

  1. Position between \w and \w

  2. ^ position between \w

  3. Position between \w and $

So:

The first word, you, fits the rule 2.

The second word “come” fits the rule

The third word is in accordance with go, in accordance with rule 3


const wordRegex = /\b/g

console.log('You say come, go is go'.replace(/\b/g.' ')) // 'You say come, go'

Copy the code

20. The case of the string is reversed

Reverse the case of the string, for example, Hello WORLD => Hello WORLD

The parsing process

This problem is easy to think of the ASCII code to determine the case, and then convert to the corresponding value, but since it is the sum of the re, we will try to complete through the re.

How do you determine if a character is uppercase without using ASCII? In fact, if you make it uppercase and compare it to metacharacters, it means that the distal character is uppercase. Such as

For the string x = 'A' 'A'.toupperCase () y is A y === x then x is uppercaseCopy the code

So they could write it like this


const stringCaseReverseReg = /[a-z]/ig
const string = 'hello WORLD'

const string2 = string.replace(stringCaseReverseReg, (char) = > {
  const upperStr = char.toUpperCase()
  // Uppercase to lowercase, lowercase to uppercase
  return upperStr === char ? char.toLowerCase() : upperStr
})

console.log(string2) // HELLO world


Copy the code

21. Under WindowsfileFolder and file path

The following paths must be matched

  1. C:\Documents\Newsletters\Summer2018.pdf

  2. C:\Documents\Newsletters\

  3. C:\Documents\Newsletters

  4. C:\

Regular results


const windowsPathRegex = /^[a-zA-Z]:\\(? :[^\\:*<>|"?\r\n/]+\\?) * (? : (? :[^\\:*<>|"?\r\n/]+)\.\w+)? $/;
Copy the code

The parsing process

File rules in Windows consist of these parts

Disk letter :\ folder \ folder \ file

  1. Disk letter: can only be [A-za_z]:\\

  2. Folder name: does not contain special symbols and can appear at any time, the final \ can not ([^ \ \ : * < > | “? \ r \ n /] + \ \?) *

  3. File name: [[^ \ \ : * < > | “? \ r \ n /] +) \ \ w +, but can not file

const windowsPathRegex = /^[a-zA-Z]:\\(? :[^\\:*<>|"?\r\n/]+\\?) * (? : (? :[^\\:*<>|"?\r\n/]+)\.\w+)? $/;

console.log( windowsPathRegex.test("C:\\Documents\\Newsletters\\Summer2018.pdf"));// true
console.log( windowsPathRegex.test("C:\\Documents\Newsletters\\"));// true
console.log( windowsPathRegex.test("C:\\Documents\Newsletters"));// true
console.log( windowsPathRegex.test("C:\\"));// true

Copy the code

22. Matching ID (often used when writing crawlers to get HTML)

Hello world

id box

Regular results


const matchIdRegexp = /id="([^"]*)"/

console.log(` 
      
hello world
`
.match(matchIdRegexp)[1]) Copy the code

The parsing process

In the process of crawler writing, it is often necessary to match the DOM element of the specified condition, and then do the corresponding operation. So how do I get box


<div id="box">
  hello world
</div>

Copy the code

The first one that comes to mind is the regular id=”(.*)”.

const matchIdRegexp = /id="(.*)"/

console.log(` 
      
hello world
`
.match(matchIdRegexp)[1]) Copy the code

But id=”(.*)” can easily lead to backtracking, which takes more matching time. Is there any way to optimize it?

Yes, just replace. With [^”]. When “is encountered, the re considers the match finished and no backtracking occurs.


const matchIdRegexp = /id="([^"]*)"/

console.log(` 
      
hello world
`
.match(matchIdRegexp)[1]) Copy the code

23. Match ID extension (get all IDS of the homepage HTML of gold nuggets)

Let’s see if we can get ids in bulk

Regular results

const idRegexp = /id="([^"]+)"/g

document.body.innerHTML
  .match(idRegexp)
  .map((idStr) = > idStr.replace(idRegexp, '$1'))

Copy the code

24. Greater than or equal to 0, less than or equal to 150, support the occurrence of 5, such as 145.5, used to judge the score of the test paper

Regular results


const pointRegex = For $150, | / ^ ^ (? : 1 - [9]? \d|1[0-4]\d)(? : \. 5)? $/


Copy the code

The analysis process

We can divide this problem into two parts

  1. The integer part

    1. Bits of integers
    2. 10 integers
    3. An integer in the hundreds but less than 150
  2. Decimal part:.5 or none

Try writing the integer part first


// 1. /\d/
// 2. How to express ten digits? /[1-9]\d/
// 3. How to express the ones and tens place together? / [1-9]? \d/
// 4. What about hundreds less than 150? /1[0-4]\d/

// So the integer part combined can be represented by the following re

const pointRegex = For $150, | / ^ ^ (? : 1 - [9]? \d|1[0-4]\d)? $/

console.log(pointRegex.test(0)) // true
console.log(pointRegex.test(10)) // true
console.log(pointRegex.test(100)) // true
console.log(pointRegex.test(110.5)) // false
console.log(pointRegex.test(150)) // true

Copy the code

Plus the decimal part


// The decimal part is relatively simple /(? : \. 5)? /, so the whole thing comes together

const pointRegex = For $150, | / ^ ^ (? : 1 - [9]? \d|1[0-4]\d)(? : \. 5)? $/

console.log(pointRegex.test(-1)) // false
console.log(pointRegex.test(0)) // true 
console.log(pointRegex.test(10)) // true
console.log(pointRegex.test(100)) // true
console.log(pointRegex.test(110.5)) // true
console.log(pointRegex.test(150)) // true
console.log(pointRegex.test(151)) // false


Copy the code

25. Determine the version number

The version number must be in X.Y.Z format, where XYZ must contain at least one digit

Regular results


// x.y.z
const versionRegexp = / ^ (? :\d+\.) {2}\d+$/

console.log(versionRegexp.test('1.1.1'))
console.log(versionRegexp.test('1.000.1'))
console.log(versionRegexp.test('1.000.1.1'))


Copy the code

Meet goodbye

With good re, there is a long way to go, I hope these analysis is helpful to you! If there are any errors in the article, or if you have a better canonical writing method, please feel free to mention them.