• 正则表达式(Perl 示例)


    1. 简单模式

    匹配 key 的内容,只要把 key 的内容写在一对斜线 ( / ) 中即可:

    $_ = "yabba dabba doo";
    
    if (/abba/) {
        say "It matched the string 'abba'";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    2. Unicode 模式

    a. 匹配包含特定属性的字符

    \p{PROPERTY}

    匹配属于空白符的字符,包括但不限于 空格,制表符,回车等:

    if(/\p{Space}/) {
        say "The string has some whitespace.\n";
    }
    
    • 1
    • 2
    • 3

    b. 匹配不包含特定属性的字符(注意这里 P 是大写)

    \P{PROPERTY}

    3. 元字符

    元字符2
    点号 (.)匹配任意一个字符
    星号(*)匹配前一个条目 零次或多次
    加号(+)匹配前一个条目 至少一次
    问号(?)匹配前一个条目 零次或一次
    反斜线转义
    竖线(|)或(OR),择一匹配
    方括号([])字符集,只匹配单个字符

    a. 点号(.) 是用于匹配任意一个字符的通配符,注意不包括换行符(\n)

    $_ = "betty";
    
    if (/bet.y/) {
        say "It matched!";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    如果只想匹配点号本身,在点号前面加上反斜线转义即可:

    $_ = "Mr.Smith";
    
    if (/\./) {
        say "The string has at least a dot.";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    b. 星号(*) 用来匹配前面的条目零次或者多次。
    可以这样理解,星号的符号表示正是数学运算中的乘法(times),可以乘以零次,也可以乘以一二三四五六次等等。
    参看下面代码👇:

    @_ = qw/ac abc abbc abbbbbbbbbbbbbbc adc/;
    
    foreach (@_) {
        if (/ab*c/) {
        	# 匹配 "ac"、"abc"、"abbc"、"abbbbbbbbbbbbbbc"
        	# 不匹配 "adc"
    	    say "$_ matched!";
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    星号(*)前一个条目不仅仅可以是一个字符,也可以是其他元符号,比如点号(.),修改上方代码如下:

    foreach (@_) {
        if (/a.*c/) {
            # 字符串 "adc" 也匹配上了
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    c. 加号(+) 匹配前一个条目至少一次。

    @_ = ('a.dog', 'a dog', 'a  dog', 'a    dog');
    
    foreach (@_) {
        # 匹配 "a" 和 "dog" 之间用只包含空格的字符串隔开的字符串
        if (/a +dog/) {
            # do something
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    d. 问号(?) 用于匹配前一个条目出现零次或者一次。

    @_ = qw/bamm-bamm bammbamm bamm--bamm/;
    
    foreach (@_) {
    	# 匹配 'bamm-bamm' 和 'bammbamm'
    	# 但不匹配 'bamm--bamm'
        if (/bamm-?bamm/) {
    	    # do something
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    e. 或(|) 表示要么匹配左边的内容,要么匹配右边的内容。

    $_ = "fred";
    
    if (/fred|barney|betty/) {
        # ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    f. 方括号([ ]) ,列出一组可能出现的字符,并匹配其中的一个。
    字符集通常不会单独使用,而是作为完整模式的一部分和其他元字符配合使用。

    $_ = "The HAL-9000 requires authorization to continue.";
    
    if (/HAL-[0-9]+/) {
        # 匹配至少一个数字
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    注意连字符(-)的使用,在字符集([ ])外它是个普通的字符,所以 “HAL-” 表示普通的短横线,但是在 [0-9] 它表示指定范围。如果需要在字符集中匹配连字符,需要加反斜线 (\):

    if (/[+\-*\/]/) {
        # ...
    }
    
    • 1
    • 2
    • 3

    字符集搭配脱字符(^)使用,可以指定字符集范围之外的内容。

    @_ = qw/an am and arm/;
    
    foreach (@_) {
        if (/a[^nm]/) {
            # 匹配 "arm"
            # 不匹配 "an"、"am" 和 "and"
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    4. 模式分组

    星号(*)问号(?)加号(+) 都是针对前一个条目进行匹配的,这里的条目,不仅仅只是字符或者 点号(.),也可以是字符串比如 “abba”。
    在正则表达式中用 圆括号(()) 对字符串分组,使之成为一个条目:

    @_ = qw/bingbong bingbing bongbong/;
    
    foreach (@_) {
        # 匹配条目 “bing” 零次或者 n 次
        # 这里匹配了 “bingbong” 和 “bongbong”
        # 不匹配 “bingbing”
        if (/(bing)*bong/) {
    	    # do something
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    如果想要在表达式中重用条目,可以使用捕获组。对捕获组的引用称为反向引用,表示为 \N ,其中 N 表示组的索引,起始序号为 1。

    @_ = ("yabba dabba", "yabbp dabbc", "yabcc dabcc");
    
    foreach (@_) {
        # ‘d’ 后面跟着四个字符
        # 这四个字符跟 ‘y’ 后面的四个字符是一样的
        # 匹配 "yabba dabba", "yabcc dabcc"
        # 不匹配 "yabbp dabbc"
        if (/y(....) d\1/) {
            # do something
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    多个捕获组也是可以的:

    @_ = qw/yabba dabba doo/;
    
    foreach (@_) {
        # 匹配 "yabba","dabba"
        # 不匹配 "doo"
        if (/(.)(.)\2\1/) {
    	    # do something
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Perl 5.10 开始支持反向引用的另一种写法 \g{N},这种写法可以很好地消除反向引用与模式直接量部分的二义性:

    $_ = "aa11bb";
    
    if (/(.)\111/) {
        # 是 \1,\11 还是 \111 呢?
        # 按照 perl 的逻辑,这里应该是 \111
        # 但是并没有那么多的分组
        # 低版本会直接报错,而高版本则永远无法得到正确的结果
        print "It matched!\n";
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    而采用 \g{N} 的写法,就简单明了多了:

    $_ = "aa11bb";
    
    if (/(.)\g{1}11/) {
        # do something
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    \g{N} 写法的另一个好处是可以使用负数,用来指定相对反向引用。

    $_ = "xaa11bb";
    
    if (/(.)\g{-1}11/) {
        # ...
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    使用相对方向引用的好处是,如果模式中引用的内容前面需要追加其他内容,那么绝对编号的反向引用会失效,而相对方向的反向引用却不会。

    $_ = "xaa11bb";
    
    if (/(.)(.)\g{-1}11/) {
        # 依然可以匹配 "xaa11bb"
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
  • 相关阅读:
    Windows实时运动控制软核(一):LOCAL高速接口测试之C#
    C#一些高级语法
    【数据结构初阶】(栈和队列)图文详解四道oj+三道easy概念题
    C primer plus学习笔记 —— 5、指针
    嵌入式分享合集54
    跟TED演讲学英文:Entertainment is getting an AI upgrade by Kylan Gibbs
    量子计算的奥秘与魅力:开启未来科技的钥匙(详解)
    易语言abcd排序
    游戏设计模式专栏(八):Cocos中最常见的设计模式之一
    特征工程学习笔记
  • 原文地址:https://blog.csdn.net/wenrui7868/article/details/127555574