正则能让别人给你竖起大拇指

在上篇 JS 使用正则表达式的方式 文章中我们学习了如何用正则表达式,这篇文章介绍一下如何学习正则表达式。

正则表达式比较抽象,对于初学者并不友好,起初我看了《精通正则表达式》这本书,仅看了一部分。主要在工作中没遇到比较难的正则表达式,如果有这方面需求可以深入学习。

如果你想要这本电子书,可以私信我。

正则表达式本质上是一个文本处理工具,可以对文本进行增、删、改、查操作,它比字符串提供的方法更灵活,有时候你写几十行代码用正则几行即可搞定,这时别人会给你个大拇指。比如,把一个字符串后面的 0 去掉,如果不用正则,你会如何做?

0.0100 // 0.01
0.01 // 0.01
1.00 // 1
100. // 100
100; // 100

通过正则实现:

const removeEndZero = text => {
    if (/\./.test(text)) {
        text = text.replace(/0+$/, '');
        text = text.replace(/\.$/, '');
    }
    return text;
}

正则表达式没有标准答案,同一类问题会有多种表示方法,只要能满足自己的业务需求即可,尽可能的考虑多种异常情况。它的工作方式就是从满足正则条件的子字符串,而正则中定义了字符长什么样。

正则举例

1、匹配开头结尾,正则会从头或尾匹配符合条件的字符串:

const useStartEnd = () => {
    let text = 'suyan 12 age suyan, n_name';
    // 要匹配的字符串必须以 s 开头
    // suyan
    let ret = text.match(/^s\w+/g);
    console.log('ret = ', ret);
    // 要匹配的字符串必须以 e 结尾
    ret = text.match(/\w+e$/g);
    // n_name
    console.log('ret = ', ret);
}

2、匹配某些特定的字符

const useCharGroup = () => {
    // 匹配 suyan,s不分大小写
    // [] 匹配一组可能出现的字符
    const text = 'Suyan is a suyan';
    const reg = /[Ss]uyan/g;
    let ret = text.match(reg);
    // [ 'Suyan', 'suyan' ]
    console.log('ret = ', ret);

    // 区间可表示多个字符
    const text2 = '$s.1e4G';
    // 匹配所有的数字、大小写字母
    // 如果要匹配特殊字符,使用 \ 即可
    const reg2 = /[a-zA-Z0-9]/g;
    ret = text2.match(reg2);
    // [ 's', '1', 'e', '4', 'G' ]
    console.log('ret = ', ret);

    const text3 = 'suyan';
    // ^ 取反,不能包含 sy
    // [ 'u', 'a', 'n' ]
    ret = text3.match(/[^sy]/g)
    console.log('ret = ', ret);
}

3、巧用缩写,简化正则

一些特定的字符可以表示一个字符集,无需把每个字符一一列出。

const useQuickKey = () => {
    let text = 'suyan 12 age, n_name';
    // \w 表示 [a-zA-Z0-9_],取反 \W
    let ret = text.match(/\w/g);
    // \s 匹配空白字符,空格、换行、tab
    ret = text.match(/\s/g);
    // \b 单词边界、分割成单词
    ret = text.split(/\b/g);
    console.log('ret = ', ret);
};

4、使用 . 匹配除\n\r\u2028 or \u2029外的任意字符

const useAnyChar = () => {
    let text = 'n_name';
    // . 匹配任意字符,除了不能匹配 \n
    let ret = text.match(/n.../g);
    console.log('ret = ', ret);
}

5、使用 ?,可选,表示 0 个或 1 个

const useKeXuanChar = () => {
    let text = 'Suyan is Suuyan';
    // ? 可选字符,匹配 0 个或 1 个
    // Suyan Suuyan
    let ret = text.match(/Suu?yan/g);
    console.log('ret = ', ret);
}

6、使用 {m, n},表示任意个,+ 表示 1 个或多个

const useMoreChar = () => {
    let text = '010-89283 0101-8899';
    // {3} 重复3次,即3个字符
    let ret = text.match(/\d{3}-\d{4}/g);
    // {3,4} 重复 3到4次
    ret = text.match(/\d{3,4}-\d{4}/g);
    // {1,} 1到任意多个,可用+表示
    // {0,} 0到任意多个,可用 * 表示
    console.log('ret = ', ret);
}

7、使用捕获组

const useGroup = () => {
    const text = 'image size is 300x500';
    let reg = /(\d+)x(\d+)/;
    let ret = text.match(reg);
    /** 匹配结果中包含了组
     * ret =  [
        '300x500',
        '300',
        '500',
        index: 14,
        input: 'image size is 300x500',
        groups: undefined
    ]
     */
    console.log('ret = ', ret);
}

8、使用非捕获组

const useNotGroup = () => {
    const text = 'image size is 300x500';
    // (?:x)匹配 x,但是结果中不包含 x
    let reg = /(\d+)x(?:\d+)/;
    let ret = text.match(reg);
    /** 匹配结果中包含了组
     * ret =  [
        '300x500',
        '300',
        index: 14,
        input: 'image size is 300x500',
        groups: undefined
    ]
     */
    console.log('ret = ', ret);
}

9、使用具名捕获组

const useNameGroup = () => {
    const text = 'image size is 300x500';
    // (?:x)匹配 x,并给组设置名字
    let reg = /(?\d+)x(?\d+)/;
    let ret = text.match(reg);
    /** 匹配结果中包含了组
    ret =  [
        '300x500',
        '300',
        '500',
        index: 14,
        input: 'image size is 300x500',
        groups: [Object: null prototype] { width: '300', height: '500' }
    ]
     */
    console.log('ret = ', ret.groups.width);
    console.log('ret = ', ret.groups.height);
}

最后送大家一张表:

  • ^: 从字符串开始位置匹配,^lefe:以 lefe 开头的文本;

  • $: 从字符串的结尾匹配,$lefe:以 lefe 结尾的文本;

  • *: 匹配0个或多个字符,lefe*:lef 后出现0个或多个e,lef,lefeeee 合法;

  • +: 匹配1个或多个字符,lefe+:lef 后出现1个或多个e,lefe,lefeeee 合法;

  • ?: 匹配0个或者1个字符,lefe?:lef 后出现0个或1个e,lef,lefe 合法;

  • {m}: 匹配 m 次,lefe{2}: lefe 后出现 1 个 e,lefee 合法;

  • {m,}: 匹配至少 m 次,lefe{2,}: lefe 后至少出现 1 个 e,lefee,lefeee 合法;

  • {m,n}: 匹配 m dao n 次,lefe{2,3}: lefe 后出现 1 个 或者 2 个 e,lefee,lefeee 合法;

  • \d: 匹配任意0-9的数字,比如:123,23;

  • \D: 与 \d 相反,匹配不是0-9的字符,比如:lefe;

  • \w: 匹配任何数字和字母,还有下划线,比如:lefe_x;

  • \W: 与 \w 相反;

  • \s: 匹配任何空格字符,与 [\n\t\r\f] 相同;

  • \S: 与 \s 相反;

  • \b: 匹配单词边界,比如使用正则表达式'\w*\b' 匹配 'lefe_x is wsy',将匹配到 lefe_x,is 和 wsy;

  • \B: 与 \b 相反;

  • [字符]: 匹配[]中的任意单个字符,比如[lefx] 匹配 l,e,f 和 x 中的任意一个字符;

  • [^字符]: 匹配除[]中的任意单个字符,比如[lefx] 匹配除了 l,e,f 和 x 的任意字符;

  • [a-z]: 匹配 a 到 z 任意字母;

  • A|B|C: 只能匹配 A,B 和 C 的任意一个,lefe|lefe_x|wsy 匹配 lefe 或 lefe_x 或 wsy;

  • .: 匹配除 \n, \r, \u2028 or \u2029 任何单个字符;

  • (): 分组,可以获取分组中的内容,比如:'\[UIImage imageNamed:@"(.+?)"',匹配 [UIImage imageNamed:@"lefe"] 可以从匹配结果中获取到图片的名字 lefe;

  • \数字:引用分组,比如:^<([a-z]+)>.*<\/\1>' 可以匹配hello lefe`

  • (?:): 非获取匹配,在匹配结果中将忽略这个分组;

  • (?=): 非获取匹配,正向肯定预查,正则表达式'window(?=98|95|2000)' 可以匹配 window98window95window2000 中的 window

  • (?!): 非获取匹配,正向否定预查,正则表达式'window(?!98|95|2000)' 可以匹配window2007 中的 window, 不可以匹配 window98window95window2000 中的 window

  • (?<=): 非获取匹配,反向肯定预查,正则表达式'(?<=98|95|2000)window' 可以匹配 98window95window2000window 中的 window

  • (?: 非获取匹配,反向否定预查,正则表达式'(? 可以匹配2007window 中的 window, 不可以匹配 98window95window2000window 中的 window

大家加油。前端所有的 demo 都在这里:

https://github.com/lefex/FE

正则能让别人给你竖起大拇指_第1张图片

长按关注

素燕《前端小课》

帮助 10W 人入门并进阶前端

官网:https://lefex.gitee.io/

你可能感兴趣的:(字符串,正则表达式,css,js,python)