正則表達式之「我只想要 xxx 裡面的內容」

我相信以後會用到它。

常見的信箱例子

假設我有這些信箱:

  • aaa@gmail.com
  • ccc@yahoo.com.tw
  • ddd@msn.com
  • eee@ptt.com

如果我只想要「@.」之間的文字,也就是:

  • gamil
  • yahoo
  • msn
  • ptt

應該怎麼做?

一般可能會想說用 match(regExp) 來做,像這樣:

1
2
3
const regExp = /@[a-zA-Z]+\./
const str1 = '123@yahoo.com.tw'
str1.match(regExp)

結果就拿到:[ '@yahoo.', index: 3, input: '123@yahoo.com.tw', groups: undefined ]

會發現連 @ . 一起被匹配進來了,但這不是我要的阿,該怎麼做才好呢?

在正則表達式中有一個很好用的東西叫「Capturing Groups」,會用 () 來表示,簡單來說就是把 () 中匹配的字串抓出來。所以套用剛剛的例子會變這樣:

1
2
3
const regExp = /@([a-zA-Z]+)\./
const str1 = '123@yahoo.com.tw'
str1.match(regExp)

這時候結果就不一樣了:

1
2
3
4
5
6
[
'@yahoo.',
'yahoo',
index: 3, input: '123@yahoo.com.tw',
groups: undefined
]

第二個元素就是我們要的結果了。

所以回到一開始的例子:

1
2
3
4
5
6
7
8
9
10
const regExp = /@([a-zA-Z]+)\./
const emails = [
'aaa@gmail.com',
'ccc@yahoo.com.tw',
'ddd@msn.com',
'eee@ptt.com'
]
for(let email of emails) {
console.log(email.match(regExp)[1])
}

正則表達式真的是一個很強大的東西!

進階題

上面了解之後,可以試著看能不能理解這邊段程式碼做了什麼:

1
2
3
4
5
6
7
8
9
10
const regExp = /^.+@(.+?)\./
const emails = [
'aaa@gmail.com',
'ccc@yahoo.com.tw',
'ddd@msn.com',
'eee@ptt.com'
]
for(let email of emails) {
console.log(email.match(regExp)[1])
}

其實就是把剛剛的例子寫得更完整一點,讓它可以判斷信箱的格式正確,並且把想要的內容(@. 之間)抓出來。

其中用到了 ? 的部分,意思是說找出「最少匹配」, @yahoo. 是最少的, @yahoo.com. 是最多的,而預設是會找出「最多匹配」,但我們要少的那個,所以才要加上 ?

不太懂的話可以參考:正則表達式

先理解作用域跟回傳值,再來談閉包。 mentor-program-day32
Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×