【DailyENJS第6期】JavaScript正则表达式实用指南

DailyENJS 致力于翻译优秀的前端英文技术文章,为技术同学带来更好的技术视野。

image

当你第一次遇到正则表达式时,它们看起来像是随意的乱码。虽然它们可能看起来不容易理解,但它们也非常有用。

事实上正确理解正则表达式将使你成为一个更加高效的程序员。为了完全理解正则表达式,您首先需要学习基础知识。

什么是正则表达式

正则表达式是一种描述字符串数据中的模式的方法。它们构成了自己的一种小语言,它是许多编程语言的一部分,如Javascript,Perl,Python,Php和Java。

正则表达式能够帮助你去校验字符串,如电子邮件地址或密码。

创建一个正则表达式

在Javascript中有两种方式可以创建正则表达式。可以使用RegExp构造函数创建,也可以使用正斜杠(/)来创建。

使用 RegExp 构造函数

语法: new RegExp(pattern[, flags])

例子:

var regexConst = new RegExp('abc')

使用正则表达式字面量

语法: /pattern/flags

例子:

var regexLiteral = /abc/;

这里的 flags 是可选的,文章的后面将会解释这些。

可能还有一些情况需要动态创建正则表达式,在这种情况下,正则表达式字面量不起作用,因此您必须使用正则表达式构造函数。

无论您选择哪种方法,结果都是正则表达式对象,都有相同的方法和属性。

由于正斜杠用于创建正则表达式,因此如果要将 / 用作正则表达式的一部分,则必须使用反斜杠(\)转义正斜杠(/)。

正则表达式的方法

测试正则表达式主要有两种方法。

RegExp.prototype.test()

这个方法用于测试是否已找到匹配项。它接受一个字符串作为参数,并返回true或false:

例子:

var regex = /hello/;
var str = 'hello world';
var result = regex.test(str);
console.log(result);
// returns true

RegExp.prototype.exec()

这个方法返回包含所有匹配组的数组。它接受一个字符串作为参数。

例子:

var regex = /hello/;
var str = 'hello world';
var result = regex.exec(str);
console.log(result);
// returns [ 'hello', index: 0, input: 'hello world', groups: undefined ]
// 'hello' -> is the matched pattern.
// index: -> Is where the regular expression starts.
// input: -> Is the actual string passed.

我们将在下面使用test()方法。

简单的正则表达式匹配

它是最基本的模式,它简单地将文字文本与测试字符串相匹配。例如:

var regex = /hello/;
console.log(regex.test('hello world'));
// true

特殊字符

到目前为止,我们已经创建了简单的正则表达式。现在,让我们在处理更复杂的情况时充分利用正则表达式的全部功能。

例如,不是匹配特定的电子邮件地址,而是说我们想要匹配许多电子邮件地址。这就是特殊字符发挥作用的地方。为了完全理解正则表达式,您必须记住特殊的符号和字符。

falgs

正则表达式有五个可选的flag或修饰符。让我们讨论两个最重要的flag:

  • g:全局匹配;找到所有匹配,而不是在第一个匹配后停止

  • i:忽略大小写

您还可以在单​​个正则表达式中组合修饰符。并且他们的顺序对结果没有任何影响。

接下来看看一些例子:

使用正则表达式字面量:

var regexGlobal = /abc/g;
console.log(regexGlobal.test('abc abc'));
// it will match all the occurence of 'abc', so it won't return
// after first match.
var regexInsensitive = /abc/i;
console.log(regexInsensitive.test('Abc'));
// returns true, because the case of string characters don't matter
// in case-insensitive search.

使用 RegExp 构造函数:

var regexGlobal = new RegExp('abc','g')
console.log(regexGlobal.test('abc abc'));
// it will match all the occurence of 'abc', so it won't return // after first match.
var regexInsensitive = new RegExp('abc','i')
console.log(regexInsensitive.test('Abc'));
// returns true, because the case of string characters don't matter // in case-insensitive search.

Character groups:

字符集[xyz]-字符集是一种在一个位置匹配不同字符的方法,它匹配括号内的字符中字符串中的任何单个字符。例如:

var regex = /[bt]ear/;
console.log(regex.test('tear'));
// returns true
console.log(regex.test('bear'));
// return true
console.log(regex.test('fear'));
// return false

注: 除了插入符号(^)(在字符集中具有完全不同的含义)之外的所有特殊字符在字符集内(中括号内)都会失去其特殊含义。

否定字符集(Negated character set [^xyz])—— 它匹配括号中未包含的任何内容。例如:

var regex = /[^bt]ear/;
console.log(regex.test('tear'));
// returns false
console.log(regex.test('bear'));
// return false
console.log(regex.test('fear'));
// return true

范围[a-z](Ranges[a-z]): 假设我们想要在一个位置匹配字母表中的所有字母,我们可以在括号内写出所有字母,但有一种更简单的方法,那就是范围。例如:[a-h]将匹配a到h的所有字母。范围也可以是[0-9]之类的数字或[A-Z]之类的大写字母。

var regex = /[a-z]ear/;
console.log(regex.test('fear'));
// returns true
console.log(regex.test('tear'));
// returns true

元字符(Meta-characters) - 元字符是具有特殊含义的字符。有许多元字符,但我将在这里介绍最重要的元字符。

  • \d:匹配任何数字字符(与[0-9]相同)

  • \w: 匹配任何单词字符。单词字符是任何字母,数字和下划线。(与[a-zA-Z0-9_]相同)即字母数字字符

  • \s: 匹配空白字符(空格,制表符等)

  • \t: 仅匹配制表符

  • \b: 在单词的开头或结尾找到匹配项。也称为单词边界

  • .: 匹配除换行符之外的任何字符

  • \D: 匹配任何非数字字符(与[^ 0-9]相同)

  • \W: 匹配任何非单词字符(与[^ a-zA-Z0-9_]相同)

  • \S: 匹配非空白字符

量词: 量词是在正则表达式中具有特殊含义的符号

  • +: 匹配前面的表达式1次或多次
var regex = /\d+/;
console.log(regex.test('8'));
// true
console.log(regex.test('88899'));
// true
console.log(regex.test('8888845'));
  • *: 匹配前面的表达式0次或更多次
var regex = /go*d/;
console.log(regex.test('gd'));
// true
console.log(regex.test('god'));
// true
console.log(regex.test('good'));
// true
console.log(regex.test('goood'));
// true
  • ?: 匹配前面的表达式0或1次,即前面的模式是可选的
var regex = /goo?d/;
console.log(regex.test('god'));
// true
console.log(regex.test('good'));
// true
console.log(regex.test('goood'));
// false
  • ^: 匹配字符串的开头。即插入符号(^)匹配字符串的开头。
var regex = /^g/;
console.log(regex.test('good'));
// true
console.log(regex.test('bad'));
// false
console.log(regex.test('tag'));
// false
  • )符号与字符串的结尾匹配。
var regex = /.com$/;
console.log(regex.test('[email protected]'));
// true
console.log(regex.test('test@testmail'));
// false
  • {N}: 完全匹配前面表达式N次
var regex = /go{2}d/;
console.log(regex.test('good'));
// true
console.log(regex.test('god'));
// false
  • {N,}: 匹配前面正则表达式至少N次
var regex = /go{2,}d/;
console.log(regex.test('good'));
// true
console.log(regex.test('goood'));
// true
console.log(regex.test('gooood'));
// true
  • {N,M}: 匹配前面正则表达式至少N次且最多M次(其中M> N)
var regex = /go{1,2}d/;
console.log(regex.test('god'));
// true
console.log(regex.test('good'));
// true
console.log(regex.test('goood'));
// false

Alternation X|Y: 匹配X或Y,例如:

var regex = /(green|red) apple/;
console.log(regex.test('green apple'));
// true
console.log(regex.test('red apple'));
// true
console.log(regex.test('blue apple'));
// false

注意 - 如果要将任何特殊字符用作表达式的一部分,例如,您希望匹配文字+或。,则必须使用反斜杠(\)对其进行转义。

例如:

var regex = /a+b/;  // This won't work
var regex = /a\+b/; // This will work
console.log(regex.test('a+b')); // true

高级

(x): 匹配x并记住这个匹配。这些被称为捕获组。这也用于在正则表达式中创建子表达式。例如 :

var regex = /(foo)bar\1/;
console.log(regex.test('foobarfoo'));
// true
console.log(regex.test('foobar'));
// false

\1 记住并使用括号内第一个子表达式匹配。

(?:x): 匹配x并且不记得匹配。这些被称为非捕获组。这里 \1 不起作用,它将匹配文字 \1

var regex = /(?:foo)bar\1/;
console.log(regex.test('foobarfoo'));
// false
console.log(regex.test('foobar'));
// false
console.log(regex.test('foobar\1'));
// true

x(?=y): 仅当x后跟y时才匹配x。也被称为正向先行断言。例如:

var regex = /Red(?=Apple)/;
console.log(regex.test('RedApple'));
// true

在上面的示例中,仅当Redis后跟Apple时才会进行匹配。

正则表达式练习

让我们练习一些我们上面学到的概念。

  • 匹配任何10个数字:
var regex = /^\d{10}$/;
console.log(regex.test('9995484545'));
// true

让我们看一看发生了什么。

  1. 如果我们想强制匹配整个字符串,我们可以添加量词^和匹配结尾。因此,如果字符串包含超过10位数,则不匹配

  2. \d 匹配数字字符串

  3. {10} 匹配前一个表达式,在这种情况下 \d 恰好10次。因此,如果测试字符串包含少于或大于10位数,则结果将为false。

  • 匹配日期格式DD-MM-YYYY或DD-MM-YY
var regex = /^(\d{1,2}-){2}\d{2}(\d{2})?$/;
console.log(regex.test('01-01-1990'));
// true
console.log(regex.test('01-01-90'));
// true
console.log(regex.test('01-01-190'));
// false

让我们看一看发生了什么。

  1. 同样,我们将整个正则表达式包装在^和$中,以便匹配整个字符串。
  2. ( 开始第一个子表达式
  3. \d{1,2} 匹配智商一个数字最多两个数字
  4. - 匹配连字符
  5. ) 第一个子表达式的结尾
  6. {2} 精确匹配第一个子表达式2次
  7. \d{2} 精确匹配两个数字字符
  8. (\d{2})? 精确匹配两个数字并且是可选的

结论

正则表达式有时可能相当复杂,但正确理解上述概念将有助于您轻松理解更复杂的正则表达式模式。
您可以在此处 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions 了解有关正则表达式的更多信息并可以在此处 https://www.hackerrank.com/domains/regex 练习。

最后照旧是一个广告贴,最近新开了一个分享技术的公众号,欢迎大家关注(目前关注人数可怜)

image

你可能感兴趣的:(【DailyENJS第6期】JavaScript正则表达式实用指南)