无名 发表于 2022-5-8 15:49:52

正则表达式一(续)

11. | 多个数据选一(常用于多字符)
前面提到[]里面的字符有选一个字符功能,但是假如不是一个字符,比如:http|ftp|svn 就需要用|分开,|的作用域是一直往后直到遇到括号,比如,对于源字符串
http abc
ftp abc
svn abc
http|ftp|svn abc匹配的结果是:
http和ftp和svn abc
想要匹配 http abc和ftp abc和svn abc就要使用括号把前边的协议括起来,如(http|ftp|svn) abc 可以得到预期的结果。

12. () 数据分界和取数据
上面例子(http|ftp|svn) abc就是数据分界的例子,然后,匹配结果会得到一个的子集数据(数组下标1),这里就是子模式的概念,子模式也叫分组,利用子模式,可以得到想要取出来的数据。子模式1、2、3的计算方法为左括号的计数,从左到右,从1开始,比如:
(http|ftp|svn)://([^/]+),分组1得到的是(http|ftp|svn)里面的数据,分组2得到([^/]+)里面的数据,对于嵌套括号也是点左括号即可。在正则中有很多与括号结合的写法,你在数左括号的时候,一定要注意,非捕获组和环视的左括号都是不需要数的。
在使用子模式过程中,常见两种写法是:\1 和 $1。
(1) \1 是在正则表达式本身中引用分组1的内容,如:
我们要匹配111这样的连续出现3此的数字,我们可以写出正则:(\d)\1\1,(\d)匹配到第一个1,后面再引用这个匹配内容,得到111。
(2) $1 是在替换中调用分组的内容,如:
我们要替换链接参数name=Zjmainstay为username=Zjmainstay,我们可以使用正则name=([^&]+)替换为username=$1来实现,这里的$1就引用了分组1的结果Zjmainstay,因此得到我们想要的结果。

13. (?:) 非捕获组
上面说到()作为子模式可以得到它里面的数据,但是,有些时候,()只是作为数据分界功能,并不需要取出来,这时候就要用到非捕获组的概念了。比如:(http|ftp|svn)://([^/]+)只想得到域名,也就是,那么(http|ftp|svn)就只是数据分界的功能,这里不需要捕获,因此使用非捕获组功能,(?:http|ftp|svn)屏蔽这部分的数据获取,此时,(?:这个左括号排除计数,也就是(?:http|ftp|svn)://([^/]+)中的([^/]+)变成了。

14. 分隔符
在一些语言中,你会发现正则第一个和最后一个字符是相同的,如:
/\d+/
这个/ /在PHP中称为分隔符,正则表达式需要由分隔符闭合包裹。在PHP中,分隔符可以使任意非字母数字、非反斜线、非空白字符。这个概念很关键,它能帮助我们简化一些正则的书写,避免错误,如:
/.*?/
这个正则是错误的。
原因是的/与分隔符相同,但是却没有做转义。
如下程序:
preg_match('/.*?/', 'abc', $match);
PHP中会收到错误提示:Warning: preg_match(): Unknown modifier 'd' in regexTest.php on line 2
对于这种情况,有两种解决方案:
(1)/.*?/
(2)#.*?#
方案(1)是对正则内部的分隔符做转义,方案(2)是规避了本来的/分隔符,使用#作为分隔符,从而避免/需要转义。
虽然很多情况下,都是看到前后一致的分隔符,但是,大家需要了解一下,[.*?]这个表达式在PHP里也是合法的。(只是我不提倡使用而已,不懂就微信群里问我即可,我是虫虫上仙)

15. 模式修饰符
模式修饰符在许多程序语言中都支持的,比如最常见的是i,不区分大小写,如javascript里的//i,表示匹配字母数字,不区分大小写。
在PHP中,模式修饰符有两种用法,一种是上面的,在分隔符后面的模式修饰符,它的作用范围是全局;另一种是在正则表达式中间的。
例如:
正则:/((?i)+)c/
测试字符:abcABC
匹配:abc
说明:局部(ab)的大小写被忽略了,(?i)的作用范围在分组1内
http://cdn.u1.huluxia.com/g4/M01/48/A9/rBAAdmEPwuqAY_yBAAFECrTXJiQ696.png
页: [1]
查看完整版本: 正则表达式一(续)