捕获组还可以用于对正则表达式进行部分分组,以便于重复。虽然我们将在接下来的章节中详细介绍重复,但这里有一个示例演示了组的实用性。
/a(bcd)+e/g
其他时候,它们用于对正则表达式的逻辑相似部分进行分组,以提高可读性。
/(\d\d\d\d)-W(\d\d)/g
6.2 回溯回溯允许引用之前捕获的子字符串。
匹配第一组可以使用 \1,匹配第二组可以使用 \2,依此类推…
/([abc])×\1×\1/g
不能使用回溯来减少正则表达式中的重复。它们指的是组的匹配,而不是模式。
/[abc][abc][abc]/g
/[abc]\1\1/g
下面是一个演示常见用例的示例:
/\w+([,|])\w+\1\w+/g
这不能通过重复的字符类来实现。
/\w+[,|]\w+[,|]\w+/g
6.3 非捕获组非捕获组与捕获组非常相似,只是它们不创建“捕获”。而是采取形式 (?: ...)
非捕获组通常与捕获组一起使用。也许您正在尝试使用捕获组提取匹配的某些部分。而你可能希望使用一个组而不扰乱捕获顺序,这时候你应该使用非捕获组。
6.4 例子查询字符串参数
/^\?(\w+)=(\w+)(?:&(\w+)=(\w+))*$/g
我们单独匹配第一组键值对,因为这可以让我么使用 & 分隔符, 作为重复组的一部分。
(基础的) HTML 标签
根据经验,不要使用正则表达式来匹配 XML/HTML。不过,我还是提供相关的一个例子:
/<([a-z]+)+>(.*)<\/\1>/gi
姓名
查找:\b(\w+) (\w+)\b
替换:
在替换操作,经常使用 2;捕获使用 \1, \2
替换之前
John Doe
Jane Doe
Sven Svensson
Janez Novak
Janez Kranjski
Tim Joe
替换之后
Doe, John
Doe, Jane
Svensson, Sven
Novak, Janez
Kranjski, Janez
Joe, Tim
回溯和复数
查找: \bword(s?)\b
替换: phrase$1
替换之前
This is a paragraph with some words.
Some instances of the word "word" are in their plural form: "words".
替换之后
This is a paragraph with some phrases.
Yet, some are in their singular form: "phrase".
7 重复重复是一个强大而普遍的正则表达式特性。在正则表达式中有几种表示重复的方法。
7.1 可选项我们可以使用 ?将某一部分设置成可选的(0或者1次)。
/a?/g
另一个例子:
/https?/g
我们还可以让捕获组和非捕获组编程可选的。
/url: (www\.)?example\.com/g
7.2 零次或者多次如果我们希望匹配零个或多个标记,可以用 * 作为后缀。
/a*/g
我们的正则表达式甚至匹配一个空字符串。
7.3 一次或者多次如果我们希望匹配 1 个或多个标记,可以用 + 作为后缀。
/a+/g
7.4 精确的 x 次如果我们希望匹配特定的标记正好x次,我们可以添加{x}后缀。这在功能上等同于复制粘贴该标记 x 次。
/a{3}/g
下面是匹配大写的六个字符的十六进制颜色代码的例子。
/#[0-9A-F]{6}/g
这里,标记 {6} 应用于字符集 [0-9A-F]。
7.5 最小次和最大次之间如果我们希望在最小次和最大次之间匹配一个特定标记,可以在这个标记后添加 {min,max}。
/a{2,4}/g
警告
{min,max} 中逗号后面不要有空格。
7.6 最少 x 次如果我们希望匹配一个特定的标记最少 x 次,可以在标记后添加 {x,}。 和 {min, max} 类似,只是没有上限了。
/a{2,}/g
7.7 贪婪模式的注意事项正则表达式默认使用贪婪模式。在贪婪模式下,会尽可能多的匹配符合要求的字符。
/a*/g
/".*"/g
在**重复操作符(?,*,+,...)**后面添加 ?,可以让匹配变“懒”。
/".*?"/g
在这里,这也可以通过使用[^"]代替。(这是最好的做法)。
/"[^"]*"/g
懒惰,意味着只要条件满足,就立即停止;但贪婪意味着只有条件不再满足才停止。
-Andrew S on StackOverflow
/<.+>/g
/<.+?>/g
7.8 例子比特币地址
/([13][a-km-zA-HJ-NP-Z0-9]{26,33})/g (思考: {26,33}?呢)
Youtube 视频
/(?:https?:\/\/)?(?:www\.)?youtube\.com\/watch\?.*?v=([^&\s]+).*/gm
我们可以使用锚点调整表达式不让它匹配最后一个不正确的链接,之后我们会接触到。
8 交替交替允许匹配几个短语中的一个。这比仅限于单个字符的字符组更加强大。
使用管道符号 | 把多个短语之间分开
/foo|bar|baz/g
匹配 foo, bar, 和 baz 中的一个。
如果正则中只有一部分需要“交替”,可以使用组进行包裹,捕获组和非捕获组都可以。
/Try (foo|bar|baz)/g
Try 后面跟着 foo, bar, 和 baz 中的一个。
匹配 100-250 中间的数字:
/1\d\d|2[0-4]\d|250/g
这个可以使用 Regex Numeric Range Generator 工具生成。
例子十六进制颜色
让我们改进一下之前十六进制颜色匹配的例子。
/#[0-9A-F]{6}|[0-9A-F]{3}
[0-9A-F]{6} 要放在[0-9A-F]{3}的前面,这一点非常重要。否则:
/#([0-9A-F]{3}|[0-9A-F]{6})/g
小提示
正则表达式引擎是从左边到右边的尝试交替的。
罗马数字
/^M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$/g
9 修饰符修饰符允许我们把正则表达式分成不同的 "模式"。
修饰符是 /pattern/ 后面的部分。
不同引擎支持不同的修饰符。在这里我们只讨论最常见修饰符。
9.1 全局修饰符(g)到现在为止,所有的例子都设置了全局修饰符。如果不启用全局修饰符,正则表达式匹配第一个以后将不再匹配其他任何字符。
/[aeiou]/g
/[aeiou]/