mirror of
https://github.com/freeCodeCamp/freeCodeCamp.git
synced 2026-05-28 18:26:54 +00:00
feat: spam filter project (#49873)
* chore: set up initial project * feat: steps 1-10 * feat: steps 11-20 * feat: complete steps * feat: write tests * fix: debug failing tests * chore: apply Jessica's review suggestions Co-authored-by: Jessica Wilkins <67210629+jdwilkin4@users.noreply.github.com> * chore: apply gikf's review suggestions Co-authored-by: Krzysztof G. <60067306+gikf@users.noreply.github.com> * fix: test that help regex is unmodified * chore: max width on text area * chore: reapply sem's review Co-authored-by: Sem Bauke <semboot699@gmail.com> --------- Co-authored-by: Jessica Wilkins <67210629+jdwilkin4@users.noreply.github.com> Co-authored-by: Krzysztof G. <60067306+gikf@users.noreply.github.com> Co-authored-by: Sem Bauke <semboot699@gmail.com>
This commit is contained in:
@@ -343,6 +343,10 @@
|
||||
"learn-data-structures-by-building-a-shopping-cart": {
|
||||
"title": "Learn Data Structures By Building A Shopping Cart",
|
||||
"intro": ["", ""]
|
||||
},
|
||||
"learn-regular-expressions-by-building-a-spam-filter": {
|
||||
"title": "Learn Regular Expressions by Building a Spam Filter",
|
||||
"intro": ["", ""]
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
+10
@@ -0,0 +1,10 @@
|
||||
---
|
||||
title: Introduction to the Learn Regular Expressions by Building a Spam Filter
|
||||
block: learn-regular-expressions-by-building-a-spam-filter
|
||||
superBlock: JavaScript Algorithms and Data Structures
|
||||
isBeta: true
|
||||
---
|
||||
|
||||
## Introduction to the Learn Regular Expressions by Building a Spam Filter
|
||||
|
||||
This is a test for the new project-based curriculum.
|
||||
@@ -126,5 +126,6 @@
|
||||
"learn-quadratic-equations": "Python",
|
||||
"learn-simple-and-compound-interest": "Python",
|
||||
"college-algebra-with-python-conclusion": "Python",
|
||||
"learn-data-structures-by-building-a-shopping-cart": "JavaScript"
|
||||
"learn-data-structures-by-building-a-shopping-cart": "JavaScript",
|
||||
"learn-regular-expressions-by-building-a-spam-filter": "JavaScript"
|
||||
}
|
||||
|
||||
+156
@@ -0,0 +1,156 @@
|
||||
{
|
||||
"name": "Learn Regular Expressions by Building a Spam Filter",
|
||||
"isUpcomingChange": true,
|
||||
"usesMultifileEditor": true,
|
||||
"hasEditableBoundaries": true,
|
||||
"dashedName": "learn-regular-expressions-by-building-a-spam-filter",
|
||||
"order": 12,
|
||||
"time": "5 hours",
|
||||
"template": "",
|
||||
"required": [],
|
||||
"superBlock": "2022/javascript-algorithms-and-data-structures",
|
||||
"superOrder": 4,
|
||||
"isBeta": true,
|
||||
"challengeOrder": [
|
||||
[
|
||||
"641cd18eb67c661d8a9e11f3",
|
||||
"Step 1"
|
||||
],
|
||||
[
|
||||
"641cd91d28bebe226f765d86",
|
||||
"Step 2"
|
||||
],
|
||||
[
|
||||
"641cdebe67ec0f25a4798356",
|
||||
"Step 3"
|
||||
],
|
||||
[
|
||||
"641cdefa704f232675ed98aa",
|
||||
"Step 4"
|
||||
],
|
||||
[
|
||||
"641cdf57c3f7ee276e1d9b32",
|
||||
"Step 5"
|
||||
],
|
||||
[
|
||||
"641ce03dfeca10293e05dad7",
|
||||
"Step 6"
|
||||
],
|
||||
[
|
||||
"641ce3065c50e62f97406973",
|
||||
"Step 7"
|
||||
],
|
||||
[
|
||||
"641ce3dcd0aec8309fbc9971",
|
||||
"Step 8"
|
||||
],
|
||||
[
|
||||
"641ceed81533263283835c3d",
|
||||
"Step 9"
|
||||
],
|
||||
[
|
||||
"641cf198ec366c33d6504854",
|
||||
"Step 10"
|
||||
],
|
||||
[
|
||||
"6421f6f59d665615c9e94d8a",
|
||||
"Step 11"
|
||||
],
|
||||
[
|
||||
"6421f98f4999d1179ce37cb4",
|
||||
"Step 12"
|
||||
],
|
||||
[
|
||||
"642205fa6376c818f78bb24e",
|
||||
"Step 13"
|
||||
],
|
||||
[
|
||||
"642206618bdd611a0c4e90f3",
|
||||
"Step 14"
|
||||
],
|
||||
[
|
||||
"642206e054eef81b5e3092ed",
|
||||
"Step 15"
|
||||
],
|
||||
[
|
||||
"642208bc4d44701c6fd6f65e",
|
||||
"Step 16"
|
||||
],
|
||||
[
|
||||
"64220e8cb589f61e625bf453",
|
||||
"Step 17"
|
||||
],
|
||||
[
|
||||
"64220f22dff8151f751a53a7",
|
||||
"Step 18"
|
||||
],
|
||||
[
|
||||
"64220fb017c57d20612de8b8",
|
||||
"Step 19"
|
||||
],
|
||||
[
|
||||
"64221007887f38213fa57827",
|
||||
"Step 20"
|
||||
],
|
||||
[
|
||||
"642213bf8d38b0227ed6ab0b",
|
||||
"Step 21"
|
||||
],
|
||||
[
|
||||
"64233060735ddf06451c5c8c",
|
||||
"Step 22"
|
||||
],
|
||||
[
|
||||
"64233094a1293c079b5b0996",
|
||||
"Step 23"
|
||||
],
|
||||
[
|
||||
"6423322e71f8d108608005cb",
|
||||
"Step 24"
|
||||
],
|
||||
[
|
||||
"6423331f0527840934183aba",
|
||||
"Step 25"
|
||||
],
|
||||
[
|
||||
"642335220b7d830a69eb59fb",
|
||||
"Step 26"
|
||||
],
|
||||
[
|
||||
"642335d232d7690b2d67dbaf",
|
||||
"Step 27"
|
||||
],
|
||||
[
|
||||
"64233d08f234a310e73f9496",
|
||||
"Step 28"
|
||||
],
|
||||
[
|
||||
"642344dc9390c712080432c7",
|
||||
"Step 29"
|
||||
],
|
||||
[
|
||||
"64234598ef08dd13114edae5",
|
||||
"Step 30"
|
||||
],
|
||||
[
|
||||
"6423462975f33b14056583de",
|
||||
"Step 31"
|
||||
],
|
||||
[
|
||||
"6423472aeed932150e8984b6",
|
||||
"Step 32"
|
||||
],
|
||||
[
|
||||
"64234797d84734163088961a",
|
||||
"Step 33"
|
||||
],
|
||||
[
|
||||
"6423491485db5e1786dd6434",
|
||||
"Step 34"
|
||||
],
|
||||
[
|
||||
"642349b5b7bae31af21cd5f8",
|
||||
"Step 35"
|
||||
]
|
||||
]
|
||||
}
|
||||
+182
@@ -0,0 +1,182 @@
|
||||
---
|
||||
id: 641cd18eb67c661d8a9e11f3
|
||||
title: Step 1
|
||||
challengeType: 0
|
||||
dashedName: step-1
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To begin the project, use the `.getElementById()` method to retrieve the `#message-input`, `#result`, and `#check-message-btn` elements from the HTML document, and assign them to the variables `messageInput`, `result`, and `checkMessageButton`, respectively.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use `const` to declare a `messageInput` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+messageInput\s*=/);
|
||||
```
|
||||
|
||||
Your `messageInput` variable should have the value of `document.getElementById('message-input')`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(messageInput, document.getElementById('message-input'));
|
||||
```
|
||||
|
||||
You should use `const` to declare a `result` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+result\s*=/);
|
||||
```
|
||||
|
||||
Your `result` variable should have the value of `document.getElementById('result')`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(result, document.getElementById('result'));
|
||||
```
|
||||
|
||||
You should use `const` to declare a `checkMessageButton` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+checkMessageButton\s*=/);
|
||||
```
|
||||
|
||||
Your `checkMessageButton` variable should have the value of `document.getElementById('check-message-btn')`.
|
||||
|
||||
```js
|
||||
assert.deepEqual(checkMessageButton, document.getElementById('check-message-btn'));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+168
@@ -0,0 +1,168 @@
|
||||
---
|
||||
id: 641cd91d28bebe226f765d86
|
||||
title: Step 2
|
||||
challengeType: 0
|
||||
dashedName: step-2
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Attach an event listener to your `checkMessageButton`, listening for the `click` event. Give it an empty callback function.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should call `.addEventListener()` on your `checkMessageButton` element.
|
||||
|
||||
```js
|
||||
assert.match(code, /checkMessageButton\.addEventListener\(/);
|
||||
```
|
||||
|
||||
Your `.addEventListener()` method should have a `click` event type.
|
||||
|
||||
```js
|
||||
assert.match(code, /checkMessageButton\.addEventListener\(\s*('|"|`)click\1\s*,/);
|
||||
```
|
||||
|
||||
Your `.addEventListener()` method should have an empty callback function.
|
||||
|
||||
```js
|
||||
assert.match(code, /checkMessageButton\.addEventListener\(\s*('|"|`)click\1\s*,\s*\(\s*\)\s*=>\s*\{\s*\}\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+178
@@ -0,0 +1,178 @@
|
||||
---
|
||||
id: 641cdebe67ec0f25a4798356
|
||||
title: Step 3
|
||||
challengeType: 0
|
||||
dashedName: step-3
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If the `messageInput` is empty, display an alert to the user with the message `Please enter a message.`.
|
||||
|
||||
Then, exit the function execution.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your callback function should have an `if` statement.
|
||||
|
||||
```js
|
||||
assert.match(code, /checkMessageButton\.addEventListener\(\s*('|"|`)click\1\s*,\s*\(\s*\)\s*=>\s*\{\s*if\s*\(/)
|
||||
```
|
||||
|
||||
Your `if` statement should check if the `value` of `messageInput` is an empty string.
|
||||
|
||||
```js
|
||||
assert.match(code, /checkMessageButton\.addEventListener\(\s*('|"|`)click\1\s*,\s*\(\s*\)\s*=>\s*\{\s*if\s*\(\s*messageInput\.value\s*===\s*('|"|`)\2\s*\)/)
|
||||
```
|
||||
|
||||
Your `if` statement should display an alert to the user with the message `Please enter a message.`.
|
||||
|
||||
```js
|
||||
assert.match(code, /checkMessageButton\.addEventListener\(\s*('|"|`)click\1\s*,\s*\(\s*\)\s*=>\s*\{\s*if\s*\(\s*messageInput\.value\s*===\s*('|"|`)\2\s*\)\s*\{\s*alert\(\s*('|"|`)Please enter a message\.\3\s*\)/)
|
||||
```
|
||||
|
||||
Your `if` statement should exit the function execution.
|
||||
|
||||
```js
|
||||
assert.match(code, /checkMessageButton\.addEventListener\(\s*('|"|`)click\1\s*,\s*\(\s*\)\s*=>\s*\{\s*if\s*\(\s*messageInput\.value\s*===\s*('|"|`)\2\s*\)\s*\{\s*alert\(\s*('|"|`)Please enter a message\.\3\s*\);?\s*return\s*;?\s*\}\s*\}/)
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
--fcc-editable-region--
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
|
||||
});
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
---
|
||||
id: 641cdefa704f232675ed98aa
|
||||
title: Step 4
|
||||
challengeType: 0
|
||||
dashedName: step-4
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Create an `isSpam` function using the `const` keyword and arrow syntax. The function should take a single parameter `msg` and implicitly return `false` for now.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use `const` to delcare an `isSpam` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+isSpam\s*=/);
|
||||
```
|
||||
|
||||
You should use arrow syntax to assign `isSpam` a function.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+isSpam\s*=\s*\(?.*\)?\s*=>/);
|
||||
```
|
||||
|
||||
Your `isSpam` function should have a single `msg` parameter.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+isSpam\s*=\s*\(?\s*msg\s*\)?/);
|
||||
```
|
||||
|
||||
Your `isSpam` function should implicitly return `false`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+isSpam\s*=\s*\(?\s*msg\s*\)?\s*=>\s*false;?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
});
|
||||
```
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
---
|
||||
id: 641cdf57c3f7ee276e1d9b32
|
||||
title: Step 5
|
||||
challengeType: 0
|
||||
dashedName: step-5
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Back in your event listener, you need to update the text of the `result` element.
|
||||
|
||||
Use a ternary operator to update the text of the `result` element after the `if` statement. Check the truthiness of calling `isSpam()` on the value of the `messageInput` element. If true, set the text to `Oh no! This looks like a spam message.`. Otherwise, set the text to `This message does not seem to contain any spam.`
|
||||
|
||||
Then set the `messageInput` element's value to an empty string.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use the assignment operator to set the `textContent` property of the `result` element.
|
||||
|
||||
```js
|
||||
assert.match(code, /checkMessageButton\.addEventListener\(\s*('|"|`)click\1\s*,\s*\(\s*\)\s*=>\s*\{\s*if\s*\(\s*messageInput\.value\s*===\s*('|"|`)\2\s*\)\s*\{\s*alert\(\s*('|"|`)Please enter a message\.\3\s*\);?\s*return\s*;?\s*\}\s*result\.textContent\s*\=\s*/)
|
||||
```
|
||||
|
||||
You should assign the `isSpam()` function call to `result.textContent`.
|
||||
|
||||
```js
|
||||
assert.match(code, /checkMessageButton\.addEventListener\(\s*('|"|`)click\1\s*,\s*\(\s*\)\s*=>\s*\{\s*if\s*\(\s*messageInput\.value\s*===\s*('|"|`)\2\s*\)\s*\{\s*alert\(\s*('|"|`)Please enter a message\.\3\s*\);?\s*return\s*;?\s*\}\s*result\.textContent\s*\=\s*isSpam\(\s*messageInput\.value\s*\)/)
|
||||
```
|
||||
|
||||
You should use ternary syntax to check the truthiness of `isSpam(messageInput.value)`.
|
||||
|
||||
```js
|
||||
assert.match(code, /checkMessageButton\.addEventListener\(\s*('|"|`)click\1\s*,\s*\(\s*\)\s*=>\s*\{\s*if\s*\(\s*messageInput\.value\s*===\s*('|"|`)\2\s*\)\s*\{\s*alert\(\s*('|"|`)Please enter a message\.\3\s*\);?\s*return\s*;?\s*\}\s*result\.textContent\s*\=\s*isSpam\(\s*messageInput\.value\s*\)\s*\?/)
|
||||
```
|
||||
|
||||
The truthy expression of your ternary should set the `textContent` property of the `result` element to `Oh no! This looks like a spam message.`.
|
||||
|
||||
```js
|
||||
assert.match(code, /checkMessageButton\.addEventListener\(\s*('|"|`)click\1\s*,\s*\(\s*\)\s*=>\s*\{\s*if\s*\(\s*messageInput\.value\s*===\s*('|"|`)\2\s*\)\s*\{\s*alert\(\s*('|"|`)Please enter a message\.\3\s*\);?\s*return\s*;?\s*\}\s*result\.textContent\s*\=\s*isSpam\(\s*messageInput\.value\s*\)\s*\?\s*('|"|`)Oh no! This looks like a spam message.\4\s*:/);
|
||||
```
|
||||
|
||||
The falsy expression of your ternary should set the `textContent` property of the `result` element to `This message does not seem to contain any spam.`.
|
||||
|
||||
```js
|
||||
assert.match(code, /checkMessageButton\.addEventListener\(\s*('|"|`)click\1\s*,\s*\(\s*\)\s*=>\s*\{\s*if\s*\(\s*messageInput\.value\s*===\s*('|"|`)\2\s*\)\s*\{\s*alert\(\s*('|"|`)Please enter a message\.\3\s*\);?\s*return\s*;?\s*\}\s*result\.textContent\s*\=\s*isSpam\(\s*messageInput\.value\s*\)\s*\?\s*('|"|`)Oh no! This looks like a spam message.\4\s*:\s*('|"|`)This message does not seem to contain any spam.\5;?\s*/);
|
||||
```
|
||||
|
||||
After your ternary, set the `value` of `messageInput` to an empty string.
|
||||
|
||||
```js
|
||||
assert.match(code, /checkMessageButton\.addEventListener\(\s*('|"|`)click\1\s*,\s*\(\s*\)\s*=>\s*\{\s*if\s*\(\s*messageInput\.value\s*===\s*('|"|`)\2\s*\)\s*\{\s*alert\(\s*('|"|`)Please enter a message\.\3\s*\);?\s*return\s*;?\s*\}\s*result\.textContent\s*\=\s*isSpam\(\s*messageInput\.value\s*\)\s*\?\s*('|"|`)Oh no! This looks like a spam message.\4\s*:\s*('|"|`)This message does not seem to contain any spam.\5;?\s*messageInput\.value\s*=\s*('|"|`)\6;?\s*\}/)
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const isSpam = (msg) => false;
|
||||
|
||||
--fcc-editable-region--
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
});
|
||||
--fcc-editable-region--
|
||||
```
|
||||
+188
@@ -0,0 +1,188 @@
|
||||
---
|
||||
id: 641ce03dfeca10293e05dad7
|
||||
title: Step 6
|
||||
challengeType: 0
|
||||
dashedName: step-6
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Your first regular expression will be used to catch help requests. Declare a `helpRegex` variable, and assign it a regular expression that matches the string `please help`.
|
||||
|
||||
As a refresher, here is a regular expression to match the string `hello world`:
|
||||
|
||||
```js
|
||||
const regex = /hello world/;
|
||||
```
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use `const` to declare a `helpRegex` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+helpRegex\s*=/);
|
||||
```
|
||||
|
||||
Your `helpRegex` variable should be a regular expression.
|
||||
|
||||
```js
|
||||
assert.instanceOf(helpRegex, RegExp);
|
||||
```
|
||||
|
||||
Your `helpRegex` variable should match the string `please help`.
|
||||
|
||||
```js
|
||||
assert.match('please help', helpRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
const isSpam = (msg) => false;
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+172
@@ -0,0 +1,172 @@
|
||||
---
|
||||
id: 641ce3065c50e62f97406973
|
||||
title: Step 7
|
||||
challengeType: 0
|
||||
dashedName: step-7
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Regular expressions can take <dfn>flags</dfn> to modify their behavior. For instance, the `i` flag can be used to make the expression ignore case, causing it to match `hello`, `HELLO`, and `Hello` for the expression `/hello/`.
|
||||
|
||||
Flags are added after the trailing backslash. Add the `i` flag to your `helpRegex`.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `helpRegex` should have the case-insensitive `i` flag.
|
||||
|
||||
```js
|
||||
assert.include(helpRegex.flags, 'i');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
--fcc-editable-region--
|
||||
const helpRegex = /please help/;
|
||||
--fcc-editable-region--
|
||||
|
||||
const isSpam = (msg) => false;
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
---
|
||||
id: 641ce3dcd0aec8309fbc9971
|
||||
title: Step 8
|
||||
challengeType: 0
|
||||
dashedName: step-8
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Strings have a `.match()` method, which accepts a regular expression as an argument and determines if the string matches that expression.
|
||||
|
||||
Update your `isSpam()` function to implicitly return the result of calling the `.match()` method on `msg`, passing `helpRegex` as the argument.
|
||||
|
||||
Then, try entering some messages on your page and see the result.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `isSpam()` function should implicitly return the result of `msg.match(helpRegex)`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*isSpam\s*=\s*\(msg\)\s*=>\s*msg\.match\(helpRegex\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help/i;
|
||||
|
||||
--fcc-editable-region--
|
||||
const isSpam = (msg) => false;
|
||||
--fcc-editable-region--
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+174
@@ -0,0 +1,174 @@
|
||||
---
|
||||
id: 641ceed81533263283835c3d
|
||||
title: Step 9
|
||||
challengeType: 0
|
||||
dashedName: step-9
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Instead of using the `.match()` method, you can use the `.test()` method of a regular expression to test if a string matches the pattern. Unlike `.match()`, `.test()` returns a boolean value indicating whether or not the string matches the pattern.
|
||||
|
||||
Update your `isSpam()` function to use the `.test()` method of `helpRegex` to test if `msg` is a match.
|
||||
|
||||
Then, try entering some messages on your page and see the result.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `isSpam()` function should implicitly return the result of `helpRegex.test(msg)`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*isSpam\s*=\s*\(msg\)\s*=>\s*helpRegex\.test\(msg\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help/i;
|
||||
|
||||
--fcc-editable-region--
|
||||
const isSpam = (msg) => msg.match(helpRegex);
|
||||
--fcc-editable-region--
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+184
@@ -0,0 +1,184 @@
|
||||
---
|
||||
id: 641cf198ec366c33d6504854
|
||||
title: Step 10
|
||||
challengeType: 0
|
||||
dashedName: step-10
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The <dfn>alternate sequence</dfn> `|` can be used to match either the text on the left or the text on the right of the `|`. For example, the regular expression `/yes|no/` will match either `yes` or `no`.
|
||||
|
||||
Update your `helpRegex` to match either `please help` or `assist me`.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `helpRegex` should use the `|` alternate sequence.
|
||||
|
||||
```js
|
||||
assert.match(helpRegex.toString(), /\|/);
|
||||
```
|
||||
|
||||
Your `helpRegex` should match the string `please help`.
|
||||
|
||||
```js
|
||||
assert.match('please help', helpRegex);
|
||||
```
|
||||
|
||||
Your `helpRegex` should match the string `assist me`.
|
||||
|
||||
```js
|
||||
assert.match('assist me', helpRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
--fcc-editable-region--
|
||||
const helpRegex = /please help/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const isSpam = (msg) => helpRegex.test(msg);
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
---
|
||||
id: 6421f6f59d665615c9e94d8a
|
||||
title: Step 11
|
||||
challengeType: 0
|
||||
dashedName: step-11
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Before you start creating additional regular expressions, you need to update your application to check more than one regular expression.
|
||||
|
||||
Start by declaring a `denyList` variable. Assign it an array containing your `helpRegex`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use `const` to declare a `denyList` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*denyList\s*=/);
|
||||
```
|
||||
|
||||
Your `denyList` variable should be an array.
|
||||
|
||||
```js
|
||||
assert.isArray(denyList);
|
||||
```
|
||||
|
||||
Your `denyList` array should have `helpRegex` as its only element.
|
||||
|
||||
```js
|
||||
assert.deepEqual(denyList, [helpRegex]);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
const isSpam = (msg) => helpRegex.test(msg);
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
---
|
||||
id: 6421f98f4999d1179ce37cb4
|
||||
title: Step 12
|
||||
challengeType: 0
|
||||
dashedName: step-12
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Remember that arrays have a `.some()` method. Use the `.some()` method to check if testing your `msg` on any of your `denyList` regular expressions returns `true`.
|
||||
|
||||
Use `regex` as the parameter for the callback function, for clarity.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `isSpam` function should implicitly return the result of `denyList.some()`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*isSpam\s*=\s*\(?\s*msg\s*\)?\s*=>\s*/)
|
||||
```
|
||||
|
||||
Your `.some()` method should use arrow syntax for the callback.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*isSpam\s*=\s*\(?\s*msg\s*\)?\s*=>\s*denyList\.some\(\s*\(?.*\)?\s*=>/);
|
||||
```
|
||||
|
||||
Your `.some()` callback should take `regex` as the parameter.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*isSpam\s*=\s*\(?\s*msg\s*\)?\s*=>\s*denyList\.some\(\s*\(?\s*regex\s*\)?\s*=>/);
|
||||
```
|
||||
|
||||
Your `.some()` callback should implicitly return the result of testing `msg` on `regex`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*isSpam\s*=\s*\(?\s*msg\s*\)?\s*=>\s*denyList\.some\(\s*\(?\s*regex\s*\)?\s*=>\s*regex\.test\(\s*msg\s*\)\s*\)/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
|
||||
const denyList = [helpRegex];
|
||||
|
||||
--fcc-editable-region--
|
||||
const isSpam = (msg) => helpRegex.test(msg);
|
||||
--fcc-editable-region--
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
---
|
||||
id: 642205fa6376c818f78bb24e
|
||||
title: Step 13
|
||||
challengeType: 0
|
||||
dashedName: step-13
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The next regular expression you will work on is one that matches mentions of dollar amounts.
|
||||
|
||||
Start by declaring a `dollarRegex` variable, and assign it a case-insensitive regular expression that matches the text `dollars`.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use `const` to declare a `dollarRegex` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*dollarRegex\s*=/);
|
||||
```
|
||||
|
||||
Your `dollarRegex` variable should be a regular expression.
|
||||
|
||||
```js
|
||||
assert.instanceOf(dollarRegex, RegExp);
|
||||
```
|
||||
|
||||
Your `dollarRegex` should match `dollars`.
|
||||
|
||||
```js
|
||||
assert.match('dollars', dollarRegex);
|
||||
```
|
||||
|
||||
Your `dollarRegex` should be case-insensitive.
|
||||
|
||||
```js
|
||||
assert.include(dollarRegex.flags, 'i');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
---
|
||||
id: 642206618bdd611a0c4e90f3
|
||||
title: Step 14
|
||||
challengeType: 0
|
||||
dashedName: step-14
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Add your `dollarRegex` to the `denyList` array so that you can test the regular expression.
|
||||
|
||||
Then try entering a message in your app.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `denyList` array should include `dollarRegex`.
|
||||
|
||||
```js
|
||||
assert.deepInclude(denyList, dollarRegex);
|
||||
```
|
||||
|
||||
Your `denyList` array should still include `helpRegex`.
|
||||
|
||||
```js
|
||||
assert.deepInclude(denyList, helpRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /dollars/i;
|
||||
|
||||
--fcc-editable-region--
|
||||
const denyList = [helpRegex];
|
||||
--fcc-editable-region--
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+189
@@ -0,0 +1,189 @@
|
||||
---
|
||||
id: 642206e054eef81b5e3092ed
|
||||
title: Step 15
|
||||
challengeType: 0
|
||||
dashedName: step-15
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You need to match a number before the text `dollars`. While you could write out `0|1|2` and so on, regular expressions have a feature that makes this easier.
|
||||
|
||||
A <dfn>character class</dfn> is defined by square brackets, and matches any character within the brackets. For example, `[aeiou]` matches any character in the list `aeiou`. You can also define a range of characters to match using a hyphen. For example, `[a-z]` matches any character from `a` to `z`.
|
||||
|
||||
Add a character class to match the digits `0` through `9` to your `dollarRegex` expression - remember the digit must come before the word `dollars`, and there should be a space between the digit and the word.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `dollarRegex` should use a character class.
|
||||
|
||||
```js
|
||||
assert.match(dollarRegex.source, /\[.*\]/);
|
||||
```
|
||||
|
||||
Your character class should be `0-9`.
|
||||
|
||||
```js
|
||||
assert.match(dollarRegex.source, /\[0-9\]/);
|
||||
```
|
||||
|
||||
Your `dollarRegex` should match `1 dollars`.
|
||||
|
||||
```js
|
||||
assert.match('1 dollars', dollarRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
--fcc-editable-region--
|
||||
const dollarRegex = /dollars/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
---
|
||||
id: 642208bc4d44701c6fd6f65e
|
||||
title: Step 16
|
||||
challengeType: 0
|
||||
dashedName: step-16
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
The dollar value may be more than one digit. To match this, the `+` quantifier can be used - this matches one or more consecutive occurrence. For example, the regular expression `/a+/` matches one or more consecutive `a` characters.
|
||||
|
||||
Update your regular expression to match one or more consecutive digits.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `dollarRegex` should use the `+` quantifier.
|
||||
|
||||
```js
|
||||
assert.match(dollarRegex.source, /\+/);
|
||||
```
|
||||
|
||||
Your `dollarRegex` should use the `+` quantifier on your `[0-9]` character class.
|
||||
|
||||
```js
|
||||
assert.match(dollarRegex.source, /\[0-9\]\+/);
|
||||
```
|
||||
|
||||
Your `dollarRegex` should match `100 dollars`.
|
||||
|
||||
```js
|
||||
assert.match('100 dollars', dollarRegex);
|
||||
```
|
||||
|
||||
Your `dollarRegex` should match `3 dollars`.
|
||||
|
||||
```js
|
||||
assert.match('3 dollars', dollarRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
--fcc-editable-region--
|
||||
const dollarRegex = /[0-9] dollars/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+215
@@ -0,0 +1,215 @@
|
||||
---
|
||||
id: 64220e8cb589f61e625bf453
|
||||
title: Step 17
|
||||
challengeType: 0
|
||||
dashedName: step-17
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Between your digits and your `dollars` text, you want to catch place values.
|
||||
|
||||
Use the `|` token to allow `hundred`, `thousand`, `million`, or `billion` between your digits and `dollars`.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `dollarRegex` should use the `|` token.
|
||||
|
||||
```js
|
||||
assert.match(dollarRegex.source, /\|/);
|
||||
```
|
||||
|
||||
Your `dollarRegex` should have three `|` tokens.
|
||||
|
||||
```js
|
||||
assert.lengthOf(dollarRegex.source.match(/\|/g), 3);
|
||||
```
|
||||
|
||||
Your `dollarRegex` should use the `|` token to match `hundred`, `thousand`, `million`, or `billion`.
|
||||
|
||||
```js
|
||||
const placeValues = dollarRegex.source.replace("[0-9]+ ", "").replace(" dollars", "").split('|');
|
||||
assert.include(placeValues, 'hundred');
|
||||
assert.include(placeValues, 'thousand');
|
||||
assert.include(placeValues, 'million');
|
||||
assert.include(placeValues, 'billion');
|
||||
```
|
||||
|
||||
Your `dollarRegex` should match `1 hundred dollars`.
|
||||
|
||||
```js
|
||||
assert.match('1 hundred dollars', dollarRegex);
|
||||
```
|
||||
|
||||
Your `dollarRegex` should match `1 thousand dollars`.
|
||||
|
||||
```js
|
||||
assert.match('1 thousand dollars', dollarRegex);
|
||||
```
|
||||
|
||||
Your `dollarRegex` should match `1 million dollars`.
|
||||
|
||||
```js
|
||||
assert.match('1 million dollars', dollarRegex);
|
||||
```
|
||||
|
||||
Your `dollarRegex` should match `1 billion dollars`.
|
||||
|
||||
```js
|
||||
assert.match('1 billion dollars', dollarRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
--fcc-editable-region--
|
||||
const dollarRegex = /[0-9]+ dollars/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+187
@@ -0,0 +1,187 @@
|
||||
---
|
||||
id: 64220f22dff8151f751a53a7
|
||||
title: Step 18
|
||||
challengeType: 0
|
||||
dashedName: step-18
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
A <dfn>capture group</dfn> is a way to define a part of the expression that should be captured and saved for later reference. You can define a capture group by wrapping a part of your expression in parentheses. For example, `/h(i|ey) camper/` would match either `hi camper` or `hey camper`, and would capture `i` or `ey` in a group.
|
||||
|
||||
Turn your place values into a capture group.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should not change your `helpRegex` regular expression.
|
||||
|
||||
```js
|
||||
assert.match(helpRegex.source, /please help|assist me/);
|
||||
```
|
||||
|
||||
Your `dollarRegex` should use a capture group.
|
||||
|
||||
```js
|
||||
assert.match(dollarRegex.source, /\(.*\)/)
|
||||
```
|
||||
|
||||
Your `hundred|thousand|million|billion` pattern should be a capture group.
|
||||
|
||||
```js
|
||||
assert.match(dollarRegex.source, /\(hundred\|thousand\|million\|billion\)/)
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
--fcc-editable-region--
|
||||
const dollarRegex = /[0-9]+ hundred|thousand|million|billion dollars/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+181
@@ -0,0 +1,181 @@
|
||||
---
|
||||
id: 64220fb017c57d20612de8b8
|
||||
title: Step 19
|
||||
challengeType: 0
|
||||
dashedName: step-19
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now that you have your capture group, you can mark the entire pattern as an optional match. The `?` quantifier matches zero or one occurrence of the preceding character or group. For example, the regular expression `/colou?r/` matches both `color` and `colour`, because the `u` is optional.
|
||||
|
||||
Mark your capture group as optional.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `dollarRegex` should use the `?` quantifier.
|
||||
|
||||
```js
|
||||
assert.match(dollarRegex.source, /\?/);
|
||||
```
|
||||
|
||||
Your `(hundred|thousand|million|billion)` capture group should be optional.
|
||||
|
||||
```js
|
||||
assert.match(dollarRegex.source, /\(hundred\|thousand\|million\|billion\)\?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
--fcc-editable-region--
|
||||
const dollarRegex = /[0-9]+ (hundred|thousand|million|billion) dollars/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
---
|
||||
id: 64221007887f38213fa57827
|
||||
title: Step 20
|
||||
challengeType: 0
|
||||
dashedName: step-20
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
One last thing with this expression. You don't actually need the match value from your capture group, so you can turn it into a <dfn>non-capturing group</dfn>. This will allow you to group the characters together without preserving the result.
|
||||
|
||||
To create a non-capturing group in a regular expression, you can add `?:` after the opening parenthesis of a group. For instance, `(?:a|b)` will match either `a` or `b`, but it will not capture the result.
|
||||
|
||||
Update your regular expression to use a non-capturing group.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `dollarRegex` should use `?:`.
|
||||
|
||||
```js
|
||||
assert.match(dollarRegex.source, /\?:/);
|
||||
```
|
||||
|
||||
Your `dollarRegex` should use a non-capturing group.
|
||||
|
||||
```js
|
||||
assert.match(dollarRegex.source, /\(\?:.*\)/);
|
||||
```
|
||||
|
||||
Your `(hundred|thousand|million|billion)` should be a non-capturing group.
|
||||
|
||||
```js
|
||||
assert.match(dollarRegex.source, /\(\?:hundred\|thousand\|million\|billion\)/);
|
||||
```
|
||||
|
||||
Your `(hundred|thousand|million|billion)` group should still be optional.
|
||||
|
||||
```js
|
||||
assert.match(dollarRegex.source, /\(\?:hundred\|thousand\|million\|billion\)\?/);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
--fcc-editable-region--
|
||||
const dollarRegex = /[0-9]+ (hundred|thousand|million|billion)? dollars/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+192
@@ -0,0 +1,192 @@
|
||||
---
|
||||
id: 642213bf8d38b0227ed6ab0b
|
||||
title: Step 21
|
||||
challengeType: 0
|
||||
dashedName: step-21
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Your next regular expression will look for strings like `free money`. Start by declaring a `freeRegex` variable and assigning it a regular expression that will match the string `free money`. Remember to make it case-insensitive.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should declare a `freeRegex` variable using `const`.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s*freeRegex\s*=/);
|
||||
```
|
||||
|
||||
Your `freeRegex` variable should be a regular expression.
|
||||
|
||||
```js
|
||||
assert.instanceOf(freeRegex, RegExp);
|
||||
```
|
||||
|
||||
Your `freeRegex` should match `free money`.
|
||||
|
||||
```js
|
||||
assert.match('free money', freeRegex);
|
||||
```
|
||||
|
||||
Your `freeRegex` should be case-insensitive.
|
||||
|
||||
```js
|
||||
assert.include(freeRegex.flags, 'i');
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
---
|
||||
id: 64233060735ddf06451c5c8c
|
||||
title: Step 22
|
||||
challengeType: 0
|
||||
dashedName: step-22
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Add your new regular expression to your `denyList` array so you can test it.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `denyList` array should include your `freeRegex` variable.
|
||||
|
||||
```js
|
||||
assert.deepInclude(denyList, freeRegex);
|
||||
```
|
||||
|
||||
Your `denyList` array should include your `dollarRegex` variable.
|
||||
|
||||
```js
|
||||
assert.deepInclude(denyList, dollarRegex);
|
||||
```
|
||||
|
||||
Your `denyList` array should include your `helpRegex` variable.
|
||||
|
||||
```js
|
||||
assert.deepInclude(denyList, helpRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
const freeRegex = /free money/i;
|
||||
|
||||
--fcc-editable-region--
|
||||
const denyList = [helpRegex, dollarRegex];
|
||||
--fcc-editable-region--
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+200
@@ -0,0 +1,200 @@
|
||||
---
|
||||
id: 64233094a1293c079b5b0996
|
||||
title: Step 23
|
||||
challengeType: 0
|
||||
dashedName: step-23
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Spam messages often use numbers instead of letters to bypass filters. Your regular expression should catch these.
|
||||
|
||||
Replace the `e` characters in your regular expression with character classes that match `e` and `3`.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `freeRegex` should use a character class.
|
||||
|
||||
```js
|
||||
assert.match(freeRegex.source, /\[.*\]/);
|
||||
```
|
||||
|
||||
Your `freeRegex` should use a character class to match `e` and `3`.
|
||||
|
||||
```js
|
||||
assert.match(freeRegex.source, /\[(e3|3e)\]/);
|
||||
```
|
||||
|
||||
Your `freeRegex` should use three character classes to match `e` and `3`.
|
||||
|
||||
```js
|
||||
assert.lengthOf(freeRegex.source.match(/\[(e3|3e)\]/g), 3);
|
||||
```
|
||||
|
||||
Your `freeRegex` should match `free money`.
|
||||
|
||||
```js
|
||||
assert.match('free money', freeRegex);
|
||||
```
|
||||
|
||||
Your `freeRegex` should match `fr33 mon3y`.
|
||||
|
||||
```js
|
||||
assert.match('fr33 mon3y', freeRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
--fcc-editable-region--
|
||||
const freeRegex = /free money/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex, freeRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+186
@@ -0,0 +1,186 @@
|
||||
---
|
||||
id: 6423322e71f8d108608005cb
|
||||
title: Step 24
|
||||
challengeType: 0
|
||||
dashedName: step-24
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Now update your `o` character to match `o` and `0` (the digit).
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `freeRegex` should use a character class to match `o` and `0`.
|
||||
|
||||
```js
|
||||
assert.match(freeRegex.source, /\[(o0|0o)\]/);
|
||||
```
|
||||
|
||||
Your `freeRegex` should match `free money`.
|
||||
|
||||
```js
|
||||
assert.match('free money', freeRegex);
|
||||
```
|
||||
|
||||
Your `freeRegex` should match `fr33 m0n3y`.
|
||||
|
||||
```js
|
||||
assert.match('fr33 m0n3y', freeRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
--fcc-editable-region--
|
||||
const freeRegex = /fr[e3][e3] mon[e3]y/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex, freeRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+183
@@ -0,0 +1,183 @@
|
||||
---
|
||||
id: 6423331f0527840934183aba
|
||||
title: Step 25
|
||||
challengeType: 0
|
||||
dashedName: step-25
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Your regex should match whole words, not partial words. That is, you do not want to match `hands-free money management`.
|
||||
|
||||
To do this, start by checking for spaces before and after your pattern. You can do this by using the meta character `\s`, which will match spaces, tabs, and line breaks.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `freeRegex` should use the `\s` token.
|
||||
|
||||
```js
|
||||
assert.match(freeRegex.source, /\s/);
|
||||
```
|
||||
|
||||
Your `freeRegex` should look for spaces at the beginning and end of your pattern.
|
||||
|
||||
```js
|
||||
assert.isTrue(freeRegex.source.startsWith('\\s'));
|
||||
assert.isTrue(freeRegex.source.endsWith('\\s'));
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
--fcc-editable-region--
|
||||
const freeRegex = /fr[e3][e3] m[o0]n[e3]y/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex, freeRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+202
@@ -0,0 +1,202 @@
|
||||
---
|
||||
id: 642335220b7d830a69eb59fb
|
||||
title: Step 26
|
||||
challengeType: 0
|
||||
dashedName: step-26
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
If you try entering the message `free money`, you'll notice it doesn't match your expression! This is because `\s` doesn't match the beginning or end of the text.
|
||||
|
||||
To match the beginning of the text, you can use the `^` anchor. This asserts that your pattern match starts at the beginning of the full string.
|
||||
|
||||
Replace your first `\s` character with a non-capturing group that matches `\s` or `^`.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `freeRegex` should use a non-capturing group.
|
||||
|
||||
```js
|
||||
assert.match(freeRegex.source, /\(\?:/);
|
||||
```
|
||||
|
||||
Your `freeRegex` should use a non-capturing group to match `\s` or `^`.
|
||||
|
||||
```js
|
||||
assert.match(freeRegex.source, /\(\?:(\^\|\\s|\\s\|\^)\)/);
|
||||
```
|
||||
|
||||
Your `freeRegex` should match `it's free money time`.
|
||||
|
||||
```js
|
||||
assert.match("it's free money time", freeRegex);
|
||||
```
|
||||
|
||||
Your `freeRegex` should match `free money time`.
|
||||
|
||||
```js
|
||||
assert.match('free money time', freeRegex);
|
||||
```
|
||||
|
||||
Your `freeRegex` should not match `hands-free money time`.
|
||||
|
||||
```js
|
||||
assert.notMatch('hands-free money', freeRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
--fcc-editable-region--
|
||||
const freeRegex = /\sfr[e3][e3] m[o0]n[e3]y\s/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex, freeRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+220
@@ -0,0 +1,220 @@
|
||||
---
|
||||
id: 642335d232d7690b2d67dbaf
|
||||
title: Step 27
|
||||
challengeType: 0
|
||||
dashedName: step-27
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
You still aren't matching `free money` yet, because you need to match the end of the string as well.
|
||||
|
||||
Like the `^` anchor, you can use the `$` anchor to match the end of the string.
|
||||
|
||||
Update your regular expression to match either the end of the string or a space, like you did for the beginning of the string.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `freeRegex` should use a second non-capturing group.
|
||||
|
||||
```js
|
||||
assert.lengthOf(freeRegex.source.match(/\(\?:/g), 2);
|
||||
```
|
||||
|
||||
Your `freeRegex` should use a non-capturing group to match `\s` or `$`.
|
||||
|
||||
```js
|
||||
assert.match(freeRegex.source, /\(\?:(\$\|\\s|\\s\|\$)\)/);
|
||||
```
|
||||
|
||||
Your `freeRegex` should match `it's free money time`.
|
||||
|
||||
```js
|
||||
assert.match("it's free money time", freeRegex);
|
||||
```
|
||||
|
||||
Your `freeRegex` should match `free money time`.
|
||||
|
||||
```js
|
||||
assert.match('free money time', freeRegex);
|
||||
```
|
||||
|
||||
Your `freeRegex` should match `it's free money`.
|
||||
|
||||
```js
|
||||
assert.match("it's free money", freeRegex);
|
||||
```
|
||||
|
||||
Your `freeRegex` should match `free money`.
|
||||
|
||||
```js
|
||||
assert.match('free money', freeRegex);
|
||||
```
|
||||
|
||||
Your `freeRegex` should not match `hands-free money time`.
|
||||
|
||||
```js
|
||||
assert.notMatch('hands-free money', freeRegex);
|
||||
```
|
||||
|
||||
Your `freeRegex` should not match `free money-management`.
|
||||
|
||||
```js
|
||||
assert.notMatch('free money-management', freeRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
--fcc-editable-region--
|
||||
const freeRegex = /(?:^|\s)fr[e3][e3] m[o0]n[e3]y\s/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex, freeRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+219
@@ -0,0 +1,219 @@
|
||||
---
|
||||
id: 64233d08f234a310e73f9496
|
||||
title: Step 28
|
||||
challengeType: 0
|
||||
dashedName: step-28
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Your next regular expression will match strings like `stock alert`. Declare a `stockRegex` variable and assign it a regular expression that will match the string `stock alert`. Remember to make it case insensitive.
|
||||
|
||||
Add it to your `denyList` array as well.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use `const` to declare your `stockRegex` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+stockRegex\s*=/);
|
||||
```
|
||||
|
||||
Your `stockRegex` variable should be assigned a regular expression.
|
||||
|
||||
```js
|
||||
assert.instanceOf(stockRegex, RegExp);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `stock alert`.
|
||||
|
||||
```js
|
||||
assert.match('stock alert', stockRegex);
|
||||
```
|
||||
|
||||
Your `stockRegex` should be case-insensitive.
|
||||
|
||||
```js
|
||||
assert.include(stockRegex.flags, 'i');
|
||||
```
|
||||
|
||||
Your `denyList` array should contain `stockRegex`.
|
||||
|
||||
```js
|
||||
assert.deepInclude(denyList, stockRegex);
|
||||
```
|
||||
|
||||
Your `denyList` array should contain `freeRegex`.
|
||||
|
||||
```js
|
||||
assert.deepInclude(denyList, freeRegex);
|
||||
```
|
||||
|
||||
Your `denyList` array should contain `dollarRegex`.
|
||||
|
||||
```js
|
||||
assert.deepInclude(denyList, dollarRegex);
|
||||
```
|
||||
|
||||
Your `denyList` array should contain `helpRegex`.
|
||||
|
||||
```js
|
||||
assert.deepInclude(denyList, helpRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
const freeRegex = /(?:^|\s)fr[e3][e3] m[o0]n[e3]y(?:$|\s)/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
|
||||
const denyList = [helpRegex, dollarRegex, freeRegex];
|
||||
--fcc-editable-region--
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
---
|
||||
id: 642344dc9390c712080432c7
|
||||
title: Step 29
|
||||
challengeType: 0
|
||||
dashedName: step-29
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Like your `freeRegex`, update your `stockRegex` to replace the `e` and `o` characters with character classes to match the letter and the corresponding number.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `stockRegex` should use a character class to match the letter `e` and the number `3`.
|
||||
|
||||
```js
|
||||
assert.match(stockRegex.source, /\[(e3|3e)\]/);
|
||||
```
|
||||
|
||||
Your `stockRegex` should use a character class to match the letter `o` and the number `0`.
|
||||
|
||||
```js
|
||||
assert.match(stockRegex.source, /\[(o0|0o)\]/);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `stock alert`.
|
||||
|
||||
```js
|
||||
assert.match('stock alert', stockRegex);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `st0ck al3rt`.
|
||||
|
||||
```js
|
||||
assert.match('st0ck al3rt', stockRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
const freeRegex = /(?:^|\s)fr[e3][e3] m[o0]n[e3]y(?:$|\s)/i;
|
||||
--fcc-editable-region--
|
||||
const stockRegex = /stock alert/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex, freeRegex, stockRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+193
@@ -0,0 +1,193 @@
|
||||
---
|
||||
id: 64234598ef08dd13114edae5
|
||||
title: Step 30
|
||||
challengeType: 0
|
||||
dashedName: step-30
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Next update your `s` and `t` characters to also match `5` and `7` respectively.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `stockRegex` should use a character class to match the letter `s` and the number `5`.
|
||||
|
||||
```js
|
||||
assert.match(stockRegex.source, /\[(s5|5s)\]/);
|
||||
```
|
||||
|
||||
Your `stockRegex` should use a character class to match the letter `t` and the number `7`.
|
||||
|
||||
```js
|
||||
assert.match(stockRegex.source, /\[(t7|7t)\]/);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `stock alert`.
|
||||
|
||||
```js
|
||||
assert.match('stock alert', stockRegex);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `570ck al3r7`.
|
||||
|
||||
```js
|
||||
assert.match('570ck al3r7', stockRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
const freeRegex = /(?:^|\s)fr[e3][e3] m[o0]n[e3]y(?:$|\s)/i;
|
||||
--fcc-editable-region--
|
||||
const stockRegex = /st[o0]ck al[e3]rt/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex, freeRegex, stockRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
---
|
||||
id: 6423462975f33b14056583de
|
||||
title: Step 31
|
||||
challengeType: 0
|
||||
dashedName: step-31
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Character classes can take more than two characters. Replace your `a` character with a character class that matches `a`, `@`, and `4`.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `stockRegex` should use a character class to match `a`, `@`, and `4`.
|
||||
|
||||
```js
|
||||
assert.match(stockRegex.source, /\[(a@4|a4@|4@a|4a@|@a4|@4a)]/);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `stock alert`.
|
||||
|
||||
```js
|
||||
assert.match('stock alert', stockRegex);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `stock @lert`.
|
||||
|
||||
```js
|
||||
assert.match('stock @lert', stockRegex);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `stock 4lert`.
|
||||
|
||||
```js
|
||||
assert.match('stock 4lert', stockRegex);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `570ck 4l3r7`.
|
||||
|
||||
```js
|
||||
assert.match('570ck 4l3r7', stockRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
const freeRegex = /(?:^|\s)fr[e3][e3] m[o0]n[e3]y(?:$|\s)/i;
|
||||
--fcc-editable-region--
|
||||
const stockRegex = /[s5][t7][o0]ck al[e3]r[t7]/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex, freeRegex, stockRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+199
@@ -0,0 +1,199 @@
|
||||
---
|
||||
id: 6423472aeed932150e8984b6
|
||||
title: Step 32
|
||||
challengeType: 0
|
||||
dashedName: step-32
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Using the same syntax, update `c` to match `c`, `{`, `[`, and `(`.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `stockRegex` should use a character class to match `c`, `{`, `[`, and `(`.
|
||||
|
||||
```js
|
||||
assert.match(stockRegex.source, /\[(c\{\[\(|\{c\[\(|\[c\{\(|c\[\{\(|\{\[c\(|\[\{c\(|\[\{\(c|\{\[\(c|\(\[\{c|\[\(\{c|\{\(\[c|\(\{\[c|\(c\[\{|c\(\[\{|\[\(c\{|\(\[c\{|c\[\(\{|\[c\(\{|\{c\(\[|c\{\(\[|\(\{c\[|\{\(c\[|c\(\{\[|\(c\{\[)\]/);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `stock alert`.
|
||||
|
||||
```js
|
||||
assert.match('stock alert', stockRegex);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `570(k 4l3r7`.
|
||||
|
||||
```js
|
||||
assert.match('570(k 4l3r7', stockRegex);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `sto{k alert`.
|
||||
|
||||
```js
|
||||
assert.match('sto{k alert', stockRegex);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `sto[k alert`.
|
||||
|
||||
```js
|
||||
assert.match('sto[k alert', stockRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
const freeRegex = /(?:^|\s)fr[e3][e3] m[o0]n[e3]y(?:$|\s)/i;
|
||||
--fcc-editable-region--
|
||||
const stockRegex = /[s5][t7][o0]ck [a@4]l[e3]r[t7]/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex, freeRegex, stockRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+229
@@ -0,0 +1,229 @@
|
||||
---
|
||||
id: 64234797d84734163088961a
|
||||
title: Step 33
|
||||
challengeType: 0
|
||||
dashedName: step-33
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Finally, allow your regex to match whole words (like you did with `freeRegex`).
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `stockRegex` should use a non-capturing group.
|
||||
|
||||
```js
|
||||
assert.match(stockRegex.source, /\(\?:/);
|
||||
```
|
||||
|
||||
Your `stockRegex` should use a non-capturing group to match `\s` or `^`.
|
||||
|
||||
```js
|
||||
assert.match(stockRegex.source, /\(\?:(\^\|\\s|\\s\|\^)\)/);
|
||||
```
|
||||
|
||||
Your `stockRegex` should use a second non-capturing group.
|
||||
|
||||
```js
|
||||
assert.lengthOf(stockRegex.source.match(/\(\?:/g), 2);
|
||||
```
|
||||
|
||||
Your `stockRegex` should use a non-capturing group to match `\s` or `$`.
|
||||
|
||||
```js
|
||||
assert.match(stockRegex.source, /\(\?:(\$\|\\s|\\s\|\$)\)/);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `it's stock alert time`.
|
||||
|
||||
```js
|
||||
assert.match("it's stock alert time", stockRegex);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `stock alert time`.
|
||||
|
||||
```js
|
||||
assert.match('stock alert time', stockRegex);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `it's stock alert`.
|
||||
|
||||
```js
|
||||
assert.match("it's stock alert", stockRegex);
|
||||
```
|
||||
|
||||
Your `stockRegex` should match `stock alert`.
|
||||
|
||||
```js
|
||||
assert.match('stock alert', stockRegex);
|
||||
```
|
||||
|
||||
Your `stockRegex` should not match `hands-stock alert time`.
|
||||
|
||||
```js
|
||||
assert.notMatch('hands-stock alert', stockRegex);
|
||||
```
|
||||
|
||||
Your `stockRegex` should not match `stock alert-management`.
|
||||
|
||||
```js
|
||||
assert.notMatch('stock alert-management', stockRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
const freeRegex = /(?:^|\s)fr[e3][e3] m[o0]n[e3]y(?:$|\s)/i;
|
||||
--fcc-editable-region--
|
||||
const stockRegex = /[s5][t7][o0][c{[(]k [a@4]l[e3]r[t7]/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex, freeRegex, stockRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+224
@@ -0,0 +1,224 @@
|
||||
---
|
||||
id: 6423491485db5e1786dd6434
|
||||
title: Step 34
|
||||
challengeType: 0
|
||||
dashedName: step-34
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
Your final regular expression will look for strings like `dear friend`. Declare a `dearRegex` and assign it a regular expression that will match the string `dear friend`. Remember to make it case insensitive, and add it to your `denyList` array.
|
||||
|
||||
# --hints--
|
||||
|
||||
You should use `const` to declare your `dearRegex` variable.
|
||||
|
||||
```js
|
||||
assert.match(code, /const\s+dearRegex\s*=/);
|
||||
```
|
||||
|
||||
Your `dearRegex` variable should be assigned a regular expression.
|
||||
|
||||
```js
|
||||
assert.instanceOf(dearRegex, RegExp);
|
||||
```
|
||||
|
||||
Your `dearRegex` should match `dear friend`.
|
||||
|
||||
```js
|
||||
assert.match('dear friend', dearRegex);
|
||||
```
|
||||
|
||||
Your `dearRegex` should be case-insensitive.
|
||||
|
||||
```js
|
||||
assert.include(dearRegex.flags, 'i');
|
||||
```
|
||||
|
||||
Your `denyList` array should contain `dearRegex`.
|
||||
|
||||
```js
|
||||
assert.deepInclude(denyList, dearRegex);
|
||||
```
|
||||
|
||||
Your `denyList` array should contain `stockRegex`.
|
||||
|
||||
```js
|
||||
assert.deepInclude(denyList, stockRegex);
|
||||
```
|
||||
|
||||
Your `denyList` array should contain `freeRegex`.
|
||||
|
||||
```js
|
||||
assert.deepInclude(denyList, freeRegex);
|
||||
```
|
||||
|
||||
Your `denyList` array should contain `dollarRegex`.
|
||||
|
||||
```js
|
||||
assert.deepInclude(denyList, dollarRegex);
|
||||
```
|
||||
|
||||
Your `denyList` array should contain `helpRegex`.
|
||||
|
||||
```js
|
||||
assert.deepInclude(denyList, helpRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
const freeRegex = /(?:^|\s)fr[e3][e3] m[o0]n[e3]y(?:$|\s)/i;
|
||||
const stockRegex = /(?:^|\s)[s5][t7][o0][c{[(]k [a@4]l[e3]r[t7](?:$|\s)/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
|
||||
const denyList = [helpRegex, dollarRegex, freeRegex, stockRegex];
|
||||
--fcc-editable-region--
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
+416
@@ -0,0 +1,416 @@
|
||||
---
|
||||
id: 642349b5b7bae31af21cd5f8
|
||||
title: Step 35
|
||||
challengeType: 0
|
||||
dashedName: step-35
|
||||
---
|
||||
|
||||
# --description--
|
||||
|
||||
To put everything you have learned together, update your `dearRegex` to map the vowels to the corresponding numbers (note that `i` should match `1`, and also match the pipe symbol `|`), and to match whole words.
|
||||
|
||||
With that, your spam filter project is complete.
|
||||
|
||||
# --hints--
|
||||
|
||||
Your `dearRegex` should use a character class to match `e` or `3`.
|
||||
|
||||
```js
|
||||
assert.match(dearRegex.source, /\[(e3|3e)\]/);
|
||||
```
|
||||
|
||||
Your `dearRegex` should use a character class to match `a`, `@`, or `4`.
|
||||
|
||||
```js
|
||||
assert.match(dearRegex.source, /\[(a@4|a4@|4a@|4@a|@a4|@4a)\]/);
|
||||
```
|
||||
|
||||
Your `dearRegex` should use a character class to match `i`, `1`, or `|`.
|
||||
|
||||
```js
|
||||
assert.match(dearRegex.source, /\[(i1\||i\|1|1i\||1\|i|\|1i|\|i1)\]/);
|
||||
```
|
||||
|
||||
Your `dearRegex` should use a non-capturing group.
|
||||
|
||||
```js
|
||||
assert.match(dearRegex.source, /\(\?:/);
|
||||
```
|
||||
|
||||
Your `stockRegex` should use a non-capturing group to match `\s` or `^`.
|
||||
|
||||
```js
|
||||
assert.match(dearRegex.source, /\(\?:(\^\|\\s|\\s\|\^)\)/);
|
||||
```
|
||||
|
||||
Your `dearRegex` should use a second non-capturing group.
|
||||
|
||||
```js
|
||||
assert.lengthOf(dearRegex.source.match(/\(\?:/g), 2);
|
||||
```
|
||||
|
||||
Your `dearRegex` should use a non-capturing group to match `\s` or `$`.
|
||||
|
||||
```js
|
||||
assert.match(dearRegex.source, /\(\?:(\$\|\\s|\\s\|\$)\)/);
|
||||
```
|
||||
|
||||
Your `dearRegex` should match `dear friend`.
|
||||
|
||||
```js
|
||||
assert.match('dear friend', dearRegex);
|
||||
```
|
||||
|
||||
Your `dearRegex` should match `d34r fr13nd`.
|
||||
|
||||
```js
|
||||
assert.match('d34r fr13nd', dearRegex);
|
||||
```
|
||||
|
||||
Your `dearRegex` should match `d3@r fr|3nd`.
|
||||
|
||||
```js
|
||||
assert.match('d3@r fr|3nd', dearRegex);
|
||||
```
|
||||
|
||||
Your `dearRegex` should match `my dear friend Naomi`.
|
||||
|
||||
```js
|
||||
assert.match('my dear friend Naomi', dearRegex);
|
||||
```
|
||||
|
||||
Your `dearRegex` should match `dear friend Naomi`
|
||||
|
||||
```js
|
||||
assert.match('dear friend Naomi', dearRegex);
|
||||
```
|
||||
|
||||
Your `dearRegex` should match `my dear friend`.
|
||||
|
||||
```js
|
||||
assert.match('my dear friend', dearRegex);
|
||||
```
|
||||
|
||||
Your `dearRegex` should not match `non-dear friend`.
|
||||
|
||||
```js
|
||||
assert.notMatch('non-dear friend', dearRegex);
|
||||
```
|
||||
|
||||
Your `dearRegex` should not match `dear friend-o`.
|
||||
|
||||
```js
|
||||
assert.notMatch('dear friend-o', dearRegex);
|
||||
```
|
||||
|
||||
# --seed--
|
||||
|
||||
## --seed-contents--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
const freeRegex = /(?:^|\s)fr[e3][e3] m[o0]n[e3]y(?:$|\s)/i;
|
||||
const stockRegex = /(?:^|\s)[s5][t7][o0][c{[(]k [a@4]l[e3]r[t7](?:$|\s)/i;
|
||||
--fcc-editable-region--
|
||||
const dearRegex = /dear friend/i;
|
||||
--fcc-editable-region--
|
||||
|
||||
const denyList = [helpRegex, dollarRegex, freeRegex, stockRegex, dearRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
|
||||
# --solutions--
|
||||
|
||||
```html
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<meta name="viewport" content="width=device-width" />
|
||||
<title>Learn Regular Expressions by Building a Spam Filter</title>
|
||||
<link rel="stylesheet" href="styles.css" />
|
||||
</head>
|
||||
|
||||
<body>
|
||||
<header class="main-text">
|
||||
<h1 class="title">Is this Spam?</h1>
|
||||
<p class="description">
|
||||
Enter a phrase to check if it would be marked as spam or not.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
<main>
|
||||
<label class="message-label" for="message-input">Message: </label>
|
||||
<textarea
|
||||
placeholder="Enter message here"
|
||||
value=""
|
||||
type="text"
|
||||
name="message"
|
||||
id="message-input"
|
||||
rows="10"
|
||||
cols="40"
|
||||
></textarea>
|
||||
<button class="btn" id="check-message-btn" type="button">
|
||||
Check message
|
||||
</button>
|
||||
<p id="result"></p>
|
||||
</main>
|
||||
|
||||
<footer class="footer">© freeCodeCamp</footer>
|
||||
<script src="./script.js"></script>
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
```css
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
box-sizing: border-box;
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
:root {
|
||||
--dark-grey: #1b1b32;
|
||||
--light-grey: #f5f6f7;
|
||||
--golden-yellow: #fecc4c;
|
||||
--yellow: #ffcc4c;
|
||||
--gold: #feac32;
|
||||
--orange: #ffac33;
|
||||
--dark-orange: #f89808;
|
||||
}
|
||||
|
||||
body {
|
||||
background-color: var(--dark-grey);
|
||||
color: var(--light-grey);
|
||||
}
|
||||
|
||||
body,
|
||||
#message-input:placeholder-shown {
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
textarea {
|
||||
max-width: 90%;
|
||||
}
|
||||
|
||||
.main-text {
|
||||
margin: 25px 0;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 2.5rem;
|
||||
}
|
||||
|
||||
.description {
|
||||
margin-top: 15px;
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.message-label {
|
||||
display: block;
|
||||
margin-bottom: 20px;
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
#message-input:placeholder-shown,
|
||||
textarea {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.btn {
|
||||
display: block;
|
||||
cursor: pointer;
|
||||
width: 200px;
|
||||
margin: 10px auto;
|
||||
color: var(--dark-grey);
|
||||
background-color: var(--gold);
|
||||
background-image: linear-gradient(var(--golden-yellow), var(--orange));
|
||||
border-color: var(--gold);
|
||||
border-width: 3px;
|
||||
}
|
||||
|
||||
.btn:hover {
|
||||
background-image: linear-gradient(var(--yellow), var(--dark-orange));
|
||||
}
|
||||
|
||||
#result {
|
||||
font-size: 2rem;
|
||||
margin: 20px 0;
|
||||
}
|
||||
|
||||
.footer {
|
||||
margin-top: 10px;
|
||||
}
|
||||
```
|
||||
|
||||
```js
|
||||
const messageInput = document.getElementById("message-input");
|
||||
const result = document.getElementById("result");
|
||||
const checkMessageButton = document.getElementById("check-message-btn");
|
||||
|
||||
const helpRegex = /please help|assist me/i;
|
||||
const dollarRegex = /[0-9]+ (?:hundred|thousand|million|billion)? dollars/i;
|
||||
const freeRegex = /(?:^|\s)fr[e3][e3] m[o0]n[e3]y(?:$|\s)/i;
|
||||
const stockRegex = /(?:^|\s)[s5][t7][o0][c{[(]k [a@4]l[e3]r[t7](?:$|\s)/i;
|
||||
const dearRegex = /(?:^|\s)d[e3][a@4]r fr[i1|][e3]nd(?:$|\s)/i;
|
||||
|
||||
const denyList = [helpRegex, dollarRegex, freeRegex, stockRegex, dearRegex];
|
||||
|
||||
const isSpam = (msg) => denyList.some((regex) => regex.test(msg));
|
||||
|
||||
checkMessageButton.addEventListener("click", () => {
|
||||
if (messageInput.value === "") {
|
||||
alert("Please enter a message.");
|
||||
return;
|
||||
}
|
||||
|
||||
result.textContent = isSpam(messageInput.value)
|
||||
? "Oh no! This looks like a spam message."
|
||||
: "This message does not seem to contain any spam.";
|
||||
messageInput.value = "";
|
||||
});
|
||||
```
|
||||
Reference in New Issue
Block a user