正则表达式(Regular Expression,简称 Regex)是一串字符,我们可以用它来定位和操作字符串中的某些元素。因此,我们可以:
💡 JavaScript 的正则表达式风格属于该语言的 ECMA-262 标准。这意味着你不必担心浏览器特定的兼容性问题。
在 JavaScript 中,正则表达式通常写成/pattern/modifiers这样的格式。
创建正则表达式有两种方式:
const regex = /[a-z]/;
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() 方法会在正则表达式与指定字符串之间搜索匹配项。返回 true 或 false。
const str = 'It is difficult to test if you have a virus';
const result = /virus$/.test(str);
console.log(result);
// => true
使用 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"];
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"
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
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,从而找到相关信息。
对话示例:
实现函数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"