2020 年 2 月 29 日

量词 +、*、? 和 {n}

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

一个数字是由一个或多个数字 \d 组成的序列。为了标记我们需要多少个数字,我们可以添加一个量词

数量 {n}

最简单的量词是在花括号中的一个数字:{n}

量词附加到一个字符(或一个字符类,或一个 [...] 集合等)上,并指定我们需要多少个字符。

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

精确计数:{5}

\d{5} 表示正好 5 位数字,与 \d\d\d\d\d 相同。

以下示例查找 5 位数字

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

我们可以添加 \b 来排除更长的数字:\b\d{5}\b

范围:{3,5},匹配 3-5 次

要查找 3 到 5 位数字,我们可以将限制放在花括号中:\d{3,5}

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

我们可以省略上限。

然后正则表达式 \d{3,} 查找长度为 3 或更长的数字序列

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

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

数字是一行中一个或多个数字的序列。所以正则表达式是 \d{1,}

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

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

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

简写

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

+

表示“一个或多个”,与 {1,} 相同。

例如,\d+ 查找数字

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

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

表示“零或一”,与 {0,1} 相同。换句话说,它使符号可选。

例如,模式 ou?r 查找 o 后面跟零个或一个 u,然后是 r

因此,colou?r 同时找到 colorcolour

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

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

表示“零个或多个”,与 {0,} 相同。也就是说,字符可以重复任意次数或不存在。

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

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

将其与 +(一个或多个)进行比较

alert( "100 10 1".match(/\d0+/g) ); // 100, 10
// 1 not matched, as 0+ requires at least one zero

更多示例

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

十进制小数(带小数点的数字)的正则表达式:\d+\.\d+

在行动中

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

用于“没有属性的打开 HTML 标签”的正则表达式,例如 <span><p>

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

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

    正则表达式查找以字符 '<' 开头,后面跟着一个或多个拉丁字母,最后以 '>' 结尾。

  2. 改进后:/<[a-z][a-z0-9]*>/i

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

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

正则表达式“没有属性的 HTML 标签的开始或结束标签”:/<\/?[a-z][a-z0-9]*>/i

我们在模式开头添加了一个可选的斜杠 /?。必须用反斜杠对其进行转义,否则 JavaScript 会认为它是模式的结束。

alert( "<h1>Hi!</h1>".match(/<\/?[a-z][a-z0-9]*>/gi) ); // <h1>, </h1>
为了使正则表达式更精确,我们通常需要使其更复杂。

我们可以从这些例子中看到一个共同的规律:正则表达式越精确,它就越长越复杂。

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

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

在现实生活中,两种变体都是可以接受的。这取决于我们对“额外”匹配的容忍度,以及是否可以通过其他方式轻松地从结果中删除它们。

任务

重要性:5

创建一个正则表达式来查找省略号:连续 3 个(或更多?)点。

检查它

let regexp = /your regexp/g;
alert( "Hello!... How goes?.....".match(regexp) ); // ..., .....

解决方案

let regexp = /\.{3,}/g;
alert( "Hello!... How goes?.....".match(regexp) ); // ..., .....

请注意,点是一个特殊字符,因此我们必须对其进行转义并插入为 \.

创建一个正则表达式来搜索以 #ABCDEF 格式编写的 HTML 颜色:第一个是 #,然后是 6 个十六进制字符。

使用示例

let regexp = /...your regexp.../

let str = "color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2 #12345678";

alert( str.match(regexp) )  // #121212,#AA00ef

附注:在本任务中,我们不需要其他颜色格式,例如 #123rgb(1,2,3) 等。

我们需要查找以 # 开头,后面跟着 6 个十六进制字符的字符串。

十六进制字符可以描述为 [0-9a-fA-F]。或者,如果我们使用 i 标志,则只需 [0-9a-f]

然后,我们可以使用量词 {6} 查找 6 个这样的字符。

因此,我们得到了正则表达式:/#[a-f0-9]{6}/gi

let regexp = /#[a-f0-9]{6}/gi;

let str = "color:#121212; background-color:#AA00ef bad-colors:f#fddee #fd2"

alert( str.match(regexp) );  // #121212,#AA00ef

问题是它会在更长的序列中找到颜色。

alert( "#12345678".match( /#[a-f0-9]{6}/gi ) ) // #123456

为了解决这个问题,我们可以在末尾添加 \b

// color
alert( "#123456".match( /#[a-f0-9]{6}\b/gi ) ); // #123456

// not a color
alert( "#12345678".match( /#[a-f0-9]{6}\b/gi ) ); // null
教程地图

评论

在评论之前阅读...
  • 如果您有任何改进建议,请提交 GitHub 问题或拉取请求,而不是评论。
  • 如果您不理解文章中的某些内容,请详细说明。
  • 要插入几行代码,请使用<code>标签,对于多行代码,请使用<pre>标签,对于超过 10 行的代码,请使用沙箱(plnkrjsbincodepen…)