轨道
/
JavaScript
JavaScript
/
练习
/
正则聊天机器人
正则聊天机器人

正则聊天机器人

学习练习

简介

JavaScript 中的正则表达式

正则表达式(Regular Expression,简称 Regex)是一串字符,我们可以用它来定位和操作字符串中的某些元素。因此,我们可以:

  • 搜索字符串中的文本
  • 替换字符串中的子串
  • 提取字符串中的信息

💡 JavaScript 的正则表达式风格属于该语言的 ECMA-262 标准。这意味着你不必担心浏览器特定的兼容性问题。

如何创建正则表达式

在 JavaScript 中,正则表达式通常写成/pattern/modifiers这样的格式。

创建正则表达式有两种方式:

  1. 正则表达式字面量:
const regex = /[a-z]/;
  1. 构造函数RegExp:
const regex = new RegExp('[a-z]');

这两种情况下,JavaScript 都会根据正则表达式创建一个对象。建议默认使用字面量这种不可变的写法。

如果正则表达式会发生变化,或者我们还不知道它是什么(比如来自用户的输入),就可以使用 RegExp 构造函数。

🏴‍☠️ 标志

正则表达式有一些可选的超能力,叫做flags,能提供额外的功能。

其中一些常用的标志有:

  • /g - 全局搜索
  • /i - 忽略大小写
  • /m - 多行搜索

下面是一个简单的例子:

const re = /home/gi;
const str = 'Home, sweet home.';
const myArray = str.match(re);
console.log(myArray);

=> // ["Home", "home"]

g字符让我们能够解析字符串中所有可能的匹配项。如果没有这个功能,JavaScript 只会提取出第一个匹配的Home。

忽略大小写标志/i让我们在查找模式时更加灵活。这样,我们要找的内容是大写UPPERCASE还是小写lowercase都没有关系。

使用RegExp构造函数时,添加标志的语法有所不同。

let regex = /[a-z]/gi; // literal notation
let regex = new RegExp('[a-z]', 'gi'); // constructor with string pattern as first argument
let regex = new RegExp(/[a-z]/, 'gi'); // constructor with regular expression literal as first argument (Starting with ECMAScript 6)

最常用的函数

当正则表达式与 JavaScript 现有的内置函数结合使用时,我们就能以一些强大的方式操作字符串并从中获取数据。

下面是一些最常与正则表达式一起使用的函数。

Test

test() 方法会在正则表达式与指定字符串之间搜索匹配项。返回 true 或 false。

const str = 'It is difficult to test if you have a virus';
const result = /virus$/.test(str);

console.log(result);

// => true

Match

使用 match() 方法,我们可以得到一个有用的数组,其内容取决于是否找到了匹配项。

这样,我们既能搜索,也能提取任意字符串中的信息。例如:

const funnyQuote =
  'If you see someone crying, ask if it is because of their haircut.';
const regex1 = /someone/;
const regex2 = /happy/;

funnyQuote.match(regex1);
// => ["someone", index: 11, input: "If you see someone crying, ask if it is because of their haircut.", groups: undefined]

funnyQuote.match(regex2);
// => null

当存在全局搜索标志/g时,该方法不会只返回唯一的匹配项以及索引或输入等有用信息,而是返回数组中显示的所有匹配项:

const funnyQuote =
  'If you see someone crying, ask if it is because of their haircut.';

const regex3 = /if/gi;

funnyQuote.match(regex3);
// => ["If", "if"];

Replace

JavaScript 中的 replace() 方法允许我们在给定的字符串中搜索一个值,并将其替换为想要的新值。

string.replace(searchValue, newValue);

用于搜索替换的模式可以是单个字符串,也可以是正则表达式。

let string = 'I like dogs!';
let result = string.replace('dogs', 'cats');

let string = 'I would love to travel to Japan';
let result = string.replace(/Japan/g, 'Hawaii');

此外,我们还可以在替换位置应用一个函数,以便对每个值做进一步的修改。

let text = 'Say hello to the chatbot.';
let result = text.replace(/chatbot|hello/gi, function (word) {
  return word.toUpperCase();
});
// => "Say HELLO to the CHATBOT"

Split

JavaScript 中的 split() 方法展示了使用正则表达式来操作字符串的另一种方式。

这样,我们会用正则表达式通过识别某个模式来划分给定的字符串,例如str.split(/[,.\s]/)。这个模式将用作separator。

const str = 'hello,user.how are.you';

const result = str.split(/[,.\s]/);

console.log(result);
// => ['hello', 'user', 'how', 'are', 'you']

说明

你被一家正在开发 Chatbot 的公司聘为正则表达式专家。

这个项目正处于非常基础的开发阶段,因此你的任务是用正则表达式提升 Chatbot 理解和生成自然语言的能力。

检查命令是否有效

除了聪明,Chatbot 还是一位忠诚的助手。

要向 Chatbot 提问,用户必须在命令的第一个位置说出“Chatbot”这个词。

关键字是大写还是小写都没关系。这里重要的是这个词的位置。

实现函数isValidCommand(),帮助 Chatbot 识别用户何时是在下达命令。

isValidCommand("Chatbot, play a song from the 80's.";
// => True
isValidCommand("Hey Chatbot, where is the closest pharmacy?";
// => False
isValidCommand("CHATBOT, do you have a solution for this challenge?";
// => True

移除加密的 emoji

Chatbot 很难理解人类如何使用 emoji 来表达情感。

当 Chatbot 收到用户消息时,每个 emoji 都表示为“emoji”后跟它的 id 编号。

实现 removeEmoji() 方法,让它接收一个字符串,并移除整条消息中所有 emoji 的加密内容。

不含 emoji 文本的行应原样返回。

只移除 emoji 字符串。不要尝试调整空白。

对于这个挑战,请使用构造函数语法来创建正则表达式。

removeEmoji("I love playing videogames emoji3465 it's one of my hobbies");
// => "I love playing videogames  it's one of my hobbies"

检查电话号码是否有效

考虑到 Chatbot 的功能可以下载到手机应用中,用户需要在对话中输入电话号码。

问题在于,Chatbot 只能读取并验证符合特定格式的号码。

如果号码有效(符合正则表达式指定的字符序列),Chatbot 会回复一条消息,感谢用户并确认该号码。如果号码无效,函数会告知用户这个电话号码无效。

期望的格式是:(+##) ###-###-###

checkPhoneNumber('(+34) 659-771-594');
// => "Thanks! You can now download me to your phone."
checkPhoneNumber('659-771-594');
// => "Oops, it seems like I can't reach out to 659-771-594"

获取网站链接

Chatbot 是一款非常好奇的软件。尽管它能在互联网上搜索特定主题,它还是喜欢向用户打听有趣的网站或 URL,从而找到相关信息。

对话示例:

  • Chatbot:嘿,用户名,我想学习如何用 JavaScript 编程,你知道有什么很酷的网站可以让我学吗?
  • 用户:我从 exercism.org 学到了很多。

实现函数getURL(),它能够返回一个数组,其中只包含每个网站的链接。写一个能识别任意 URL 的正则表达式会非常复杂,但 Chatbot 只需要读取简单的 URL。在这个练习中,URL 就是任意由 "." 分隔的单词序列。

getURL(
  'I learned a lot from exercism.org and developer.mozilla.org, but I found ts39.es very boring!',
);
// => ["exercism.org", "developer.mozilla.org", "ts39.es"];

向用户问好

为了存储所有与它对话过的人的数据,Chatbot 能够以这种格式从用户资料中获取全名:“smith, john”。

这样,我们希望 Chatbot 非常有礼貌,给人留下好印象。

编写函数niceToMeetYou(),它接收一个包含用户全名的字符串,并返回字符串**“Nice to meet you, John Smith”**

为了学习,请使用正则表达式中的替换方法来实现这个函数。

let str = 'Smith, John';

niceToMeetYou(str);
// => "Nice to meet you, John Smith"
通过 GitHub 编辑 链接将在新窗口或新标签页中打开
JavaScript Exercism

准备好开始 正则聊天机器人 了吗?

注册 Exercism,借助 37 个概念159 个练习 和真人导师指导,学习并掌握 JavaScript,全部免费。