Skip to content

Latest commit

 

History

History
142 lines (88 loc) · 4.78 KB

File metadata and controls

142 lines (88 loc) · 4.78 KB

量词 +, *, ? 和 {n}

假设我们有一个像这样 +7(903)-123-45-67 的字符串,并想要找到其中所有数字。但与之前不同的是,我们对单个数字不感兴趣,只对全数感兴趣:7, 903, 123, 45, 67

数字是一个或多个数字 pattern:\d 的序列。为了标记我们需要的数量,我们需要加一个 量词

数量 {n}

最简单的量词便是大括号中的数字:pattern:{n}

在一个字符(或一个字符类,或 [...] 等)后附加一个量词,用来指出我们具体需要的数量。

它有一些高级的形式,让我们看一些例子:

确切的位数:pattern:{5} : pattern:\d{5} 表示 5 位数,与 pattern:\d\d\d\d\d 相同。

下面这个例子查找一个五位数的数字:

```js run
alert( "I'm 12345 years old".match(/\d{5}/) ); //  "12345"
```

我们可以添加 `\b` 来排除位数更多的数字:`pattern:\b\d{5}\b`。

范围:pattern:{3,5},匹配 3-5 个 : 要查找 3-5 位的数字,我们可以将限制写在花括号中:pattern:\d{3,5}

```js run
alert( "I'm not 12, but 1234 years old".match(/\d{3,5}/) ); // "1234"
```

我们可以省略上限。

那么正则表达式 `pattern:\d{3,}` 就会查找位数大于等于 `3` 的数字:

```js run
alert( "I'm not 12, but 345678 years old".match(/\d{3,}/) ); // "345678"
```

让我们回到字符串 +7(903)-123-45-67

我们如果需要一个及以上的数字,就使用 pattern:\d{1,}

let str = "+7(903)-123-45-67";

let numbers = str.match(/\d{1,}/g);

alert(numbers); // 7,903,123,45,67

缩写

大多数常用的量词都有简写形式:

pattern:+ : 代表“一个或多个”,与 pattern:{1,} 相同。

例如,`pattern:\d+` 用来查找所有数字:

```js run
let str = "+7(903)-123-45-67";

alert( str.match(/\d+/g) ); // 7,903,123,45,67
```

pattern:? : 代表“零个或一个”,与 pattern:{0,1} 相同。换句话说,它使得符号变得可选。

例如,模式 `pattern:ou?r` 查找 `match:o`,后跟零个或一个 `match:u`,然后是 `match:r`。

所以 `pattern:colou?r` 会找到 `match:color` 和 `match:colour`:

```js run
let str = "Should I write color or colour?";

alert( str.match(/colou?r/g) ); // color, colour
```

pattern:* : 代表“零个及以上”,与 {0,} 相同。也就是说,字符可以出现任何次数或者不出现。

例如,`pattern:\d0*` 查找一个数字后面跟着任意数量的零(可能有很多或没有)的数字:

```js run
alert( "100 10 1".match(/\d0*/g) ); // 100, 10, 1
```

将其与 `pattern:+`(一个或更多)做比较:

```js run
alert( "100 10 1".match(/\d0+/g) ); // 100, 10
// 1 没有被匹配出来,因为 0+ 要求至少有一个 0
```

更多示例

量词是很常用的。它们是构成复杂正则表达式的主要“模块”,所以让我们看更多示例。

小数的正则表达式(带浮点的数字):pattern:\d+\.\d+

实现:

alert( "0 1 12.345 7890".match(/\d+\.\d+/g) ); // 12.345

”没有特性(attribute)的打开的 HTML 标签(例如 <span><p>)“的正则表达式。

  1. 最简单的:pattern:/<[a-z]+>/i

    alert( "<body> ... </body>".match(/<[a-z]+>/gi) ); // <body>

    正则表达式查找的匹配项是字符 pattern:'<' 后跟一个或多个拉丁字母,然后是 pattern:'>'

  2. 进阶版:pattern:/<[a-z][a-z0-9]*>/i

    根据标准,HTML 标签名称可以在除了第一个位置之外的任何位置有一个数字,例如 <h1>

    alert( "<h1>Hi!</h1>".match(/<[a-z][a-z0-9]*>/gi) ); // <h1>

“打开或关闭的不带特性的 HTML 标签”的正则表达式:pattern:/<\/?[a-z][a-z0-9]*>/i

我们在模式开头附近添加了一个可选的斜杠 pattern:/?。必须用一个反斜杠转义它,否则 JavaScript 会认为它是这个模式的结束符。

alert( "<h1>Hi!</h1>".match(/<\/?[a-z][a-z0-9]*>/gi) ); // <h1>, </h1>
我们能够从这些例子中看到一个共同的规则:正则表达式越精确 —— 它就越长越复杂。

例如,对于 HTML 标签,我们可以使用更简单的正则表达式:`pattern:<\w+>`。但是由于 HTML 对标签名称有更严格的限制,所以 `pattern:<[a-z][a-z0-9]*>` 更可靠

我们可以使用 `pattern:<\w+>` 还是需要 `pattern:<[a-z][a-z0-9]*>`?

在实际开发中,这两种变体都是可以接受的。具体用哪个取决于我们对于“额外”匹配的宽容程度,以及通过其他方式将它们从结果中删除的困难程度。