-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy path12-4.html
156 lines (148 loc) · 4.72 KB
/
12-4.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
<!DOCTYPE html>
<html lang="zh-TW">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="icon" href="./public/favicon.ico" />
<meta http-equiv="cache-control" content="no-cache" />
<title></title>
<link rel="stylesheet" href=" https://necolas.github.io/normalize.css/8.0.1/normalize.css" />
<link rel="stylesheet" href="./hightlight/default.min.css" />
<link rel="stylesheet" href="./css/main.css" />
<link rel="stylesheet" href="./css/copybutton.css" />
<link rel="stylesheet" href="./css/hightlight.css" />
<script src="./hightlight/hightlight.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.11/clipboard.min.js"></script>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-BEVZJDBC7Z"></script>
<script src="./js/gtag.js"></script>
</head>
<body>
<header>
<nav>
<h1>
<span id="toggle-menu"></span>
<a href="index.html"></a>
</h1>
</nav>
</header>
<main>
<aside>
<nav></nav>
</aside>
<article>
<h2 id="12-4">12-4 正則表達式 - dotAll 模式</h2>
<p>
正則中 dot . 的意思,代表除換行符號外任意單個字符。 dotAll 針對 HTML
做數據提取的時候特別好用。 我們想把以下標籤內的數據提出來分組。在 dotAll
出來以前。我們會向下列方式處理,而這麼做會有一個難點稍後說明。
</p>
<pre><code class="language-js">
let str = `
<ul>
<li>
<a>超夢的逆襲</a>
<p>上映日期: 1998/07/18</p>
</li>
<li>
<a>洛奇亞爆誕</a>
<p>上映日期: 1999/07/17</p>
</li>
<li>
<a>結晶塔帝王</a>
<p>上映日期: 2000/07/08</p>
</li>
</ul>
`
// \s 代表匹配任何空白字串,包括空格、制表符、換頁符等等。
// (.*) 代表匹配任意內容物。 為了被免貪婪 還得加 ?。
const reg = /<li>\s+<a>(.*?)<\/a>\s+<p>(.*?)<\/p>/
reg.exec(str)
// 只提取了一個 li 內容。
// [
// str,
// '超夢的逆襲',
// '上映日期: 1998/07/18'
// ]
</code></pre>
<p>
從以上結果只有單一筆 li
內容被提取就需要寫這麼多正則內容,感覺還是挺難受的。要是需要提取的內容很多的話則會造成工作量呈指數級別上升。顯然以上正則表達式的解法並不理想。
</p>
<p>這時候我們就需要 dotAll 模式。具體做法是在結尾處加上模式修正符 s 來操作。</p>
<pre><code class="language-js">
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/s // 匹配單個
reg.exec(str)
// [
// str,
// '超夢的逆襲',
// '上映日期: 1998/07/18'
// ]
</code></pre>
<p>
每次操作只會回傳一個結果,下次操作會跳過上一次的結果接著匹配,如果不再匹配到了則會回傳
null。
</p>
<pre><code class="language-js">
const reg = /<li>.*?<a>(.*?)<\/a>.*?<p>(.*?)<\/p>/gs // 匹配多個
reg.exec(str)
// [
// str,
// '超夢的逆襲',
// '上映日期: 1998/07/18'
// ]
reg.exec(str)
// [
// str,
// '洛奇亞爆誕',
// '上映日期: 1999/07/17'
// ]
reg.exec(str)
// [
// str,
// '結晶塔帝王',
// '上映日期: 2000/07/08'
// ]
reg.exec(str)
// null
</code></pre>
<p>迴圈提取標籤轉換成陣列資料,並保存結果。</p>
<pre><code class="language-js">
let result
let data = []
while(result = reg.exec(str)) {
data.push({title:result[1], content:result[2]})
}
console.log(data)
// [{
// title: '超夢的逆襲',
// content: '上映日期: 1998/07/18'
// },
// {
// title: '洛奇亞爆誕',
// content: '上映日期: 1999/07/17'
// },
// {
// title: '結晶塔帝王',
// content: '上映日期: 2000/07/08'
// }]
</code></pre>
<p>資料來源:</p>
<p>
<a
href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/RegExp/dotAll"
>
https://developer.mozilla.org/en-US/docs/Web/JavaScript/...dotAll
</a>
</p>
<p>
<a href="https://www.youtube.com/watch?v=92aDmorH1sI">
https://www.youtube.com/watch?v=92aDmorH1sI
</a>
</p>
</article>
</main>
</body>
<script type="module" src="./js/main.js"></script>
</html>