Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

正则表达式 #8

Open
xiaoxiaosaohuo opened this issue Sep 15, 2017 · 0 comments
Open

正则表达式 #8

xiaoxiaosaohuo opened this issue Sep 15, 2017 · 0 comments

Comments

@xiaoxiaosaohuo
Copy link
Owner

元字符

元字符 描述
. 句号匹配任意单个字符除了换行符.
[ ] 字符种类. 匹配方括号内的任意字符.
[^ ] 否定的字符种类. 匹配除了方括号里的任意字符
* 匹配>=0个重复的在*号之前的字符.
+ 匹配>=1个重复的+号前的字符.
? 标记?之前的字符为可选.
{n,m} 匹配num个大括号之前的字符 (n <= num <= m).
(xyz) 字符集, 匹配与 xyz 完全相等的字符串.
| 或运算符,匹配符号前或后的字符.
\ 转义字符,用于匹配一些保留的字符 [ ] ( ) { } . * + ? ^ $ \ |
^ 从开始行开始匹配.
$ 从末端开始匹配.

字符集

字符集也叫做字符类.
方括号用来指定一个字符集.
在方括号中使用连字符来指定字符集的范围.
在方括号中的字符集不关心顺序.
例如, 表达式[Tt]he 匹配 theThe.

否定字符集

一般来说 ^ 表示一个字符串的开头, 但它用在一个方括号的开头的时候, 它表示这个字符集是否定的.
例如, 表达式[^c]ar 匹配一个后面跟着ar的除了c的任意字符.

重复次数

后面跟着元字符 +, * or ? 的, 用来指定匹配子模式的次数.
这些元字符在不同的情况下有着不同的意思.

*号匹配 在*之前的字符出现大于等于0次.
例如, 表达式 a* 匹配以0或更多个a开头的字符, 因为有0个这个条件, 其实也就匹配了所有的字符. 表达式[a-z]* 匹配一个行中所有以小写字母开头的字符串.

*字符和.字符搭配可以匹配所有的字符.*.
*和表示匹配空格的符号\s连起来用, 如表达式\s*cat\s*匹配0或更多个空格开头和0或更多个空格结尾的cat字符串.

+号匹配+号之前的字符出现 >=1 次.
例如表达式c.+t 匹配以首字母c开头以t结尾,中间跟着任意个字符的字符串.

在正则表达式中元字符 ? 标记在符号前面的字符为可选, 即出现 0 或 1 次.
例如, 表达式 [T]?he 匹配字符串 heThe.

在正则表达式中 {} 是一个量词, 常用来一个或一组字符可以重复出现的次数.
例如, 表达式 [0-9]{2,3} 匹配最少 2 位最多 3 位 0~9 的数字.

特征标群

特征标群是一组写在 (...) 中的子模式. 例如之前说的 {} 是用来表示前面一个字符出现指定次数. 但如果在 {} 前加入特征标群则表示整个标群内的字符重复 N 次. 例如, 表达式 (ab)* 匹配连续出现 0 或更多个 ab.

我们还可以在 () 中用或字符 | 表示或. 例如, (c|g|p)ar 匹配 cargarpar.

或运算符

或运算符就表示或, 用作判断条件.

例如 (T|t)he|car 匹配 (T|t)hecar.

转码特殊字符

反斜线 \ 在表达式中用于转码紧跟其后的字符. 用于指定 { } [ ] / \ + * . $ ^ | ? 这些特殊字符. 如果想要匹配这些特殊字符则要在其前面加上反斜线 \.

例如 . 是用来匹配除换行符外的所有字符的. 如果想要匹配句子中的 . 则要写成 \. 以下这个例子 \.?是选择性匹配.

简写字符集

简写 描述
. 除换行符外的所有字符
\w 匹配所有字母数字, 等同于 [a-zA-Z0-9_]
\W 匹配所有非字母数字, 即符号, 等同于: [^\w]
\d 匹配数字: [0-9]
\D 匹配非数字: [^\d]
\s 匹配所有空格字符, 等同于: [\t\n\f\r\p{Z}]
\S 匹配所有非空格字符: [^\s]
\f 匹配一个换页符
\n 匹配一个换行符
\r 匹配一个回车符
\t 匹配一个制表符
\v 匹配一个垂直制表符
\p 匹配 CR/LF (等同于 \r\n),用来匹配 DOS 行终止符

捕获组

捕获组就是把正则表达式中子表达式匹配的内容,保存到内存中以数字编号或显式命名的组里,方便后面引用。当然,这种引用既可以是在正则表达式内部,也可以是在正则表达式外部。捕获组有两种形式,一种是普通捕获组,另一种是命名捕获组,通常所说的捕获组指的是普通捕获组

普通捕获组

正则:/(\d{4})-(\d{2})-(\d\d)/
匹配格式为yyyy-MM-dd的日期,月和日分别采用了\d{2}和\d\d这两种写法


let regx = /(\d{4})-(\d{2})-(\d\d)/;
let a = "2017-08-03";
let res = a.match(regx);

//0:"2017-08-03"
//1:"2017"
//2:"08"
//3:"03"

反向引用

则表达式中,对前面捕获组捕获的内容进行引用,称为反向引用;

由于JavaScript中不支持命名捕获组,所以对于捕获组的引用就只支持普通捕获组的反向引用和$number方式的引用。程序中的引用一般在替换和匹配时使用。

var str = "AA Am 99";
var reg = /(\w)\1/g;
var res= str.match(reg);
//[AA,99]
console.log(RegExp.$1)

前后关联约束(前后预查)

前后关联约束如下:

符号 描述
?= 零宽度正预测先行断言束-存在
?! 前置约束-排除
?<= 零宽度正回顾后发断言-存在
?<! 后置约束-排除
比如 \b\w+(?=ing\b),匹配以ing结尾的单词的前面部分(除了ing以外的部分),如查找 I'm singing while you're dancing. 时,它会匹配 sing 和 danc。
它断言自身出现的位置的前面能匹配表达式exp。比如 (?<=\bre)\w+\b 会匹配以re 开头的单词的后半部分(除了 re 以外的部分),例如在查找reading a book时,它匹配 ading。
下面这个例子同时使用了这两种断言:
(?<=\s)\d+(?=\s)

匹配以空白符间隔的数字(再次强调,不包括这些空白符)。

负向零宽断言

如果我们只是想要确保某个字符没有出现,但并不想去匹配它时怎么办?
如果我们想查找这样的单词--它里面出现了字母q,但是q后面跟的不是字母u,我们可以尝试这样:

\b\w*q(?!u)\w*\b
零宽度负预测先行断言(?!exp),断言此位置的后面不能匹配表达式 exp



前置约束-排除 `?!` 用于筛选所有匹配结果, 筛选条件为 其后不跟随着定义的格式
`前置约束-排除`  定义和 `前置约束(存在)` 一样, 区别就是 `=` 替换成 `!` 也就是 `(?!...)`.

表达式 `(T|t)he(?!\sfat)` 匹配 `The` 和 `the`, 且其后不跟着 `(空格)fat`.
后置约束-排除 记作 `(?<!...)` 用于筛选所有匹配结果, 筛选条件为 其前不跟着定义的格式.
例如, 表达式 `(?<!(T|t)he\s)(cat)` 匹配 `cat`, 且其前不跟着 `The` 或 `the`.

如果我们想匹配的数据涉及到了跨行,比如下面这样的。

var multiline = require('multiline');

var text = multiline.stripIndent(function () {
/*
    head
    ```
    code code2 .code3```
    ```
    foot
*/
});

直接用 . 匹配不到 \n,所以我们需要找到一个原子,能匹配包括 \n 在内的所有字符。

这个原子的惯用写法就是 [\s\S]

var match1 = text.match(/^```[\s\S]+?^```/gm);
console.log(match1) // => [ '```\ncode code2 code3```\n```' ]

// 这里有一种很骚的写法,[^] 与 [\s\S] 等价
var match2 = text.match(/^```[^]+?^```/gm)
console.log(match2) // => [ '```\ncode code2 .code3```\n```' ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant