摘要:字符组字符组就是一组字符,在正则表达式中,它表示在同一个位置可能出现的各种字符。放在正则表达式的开头,表示定位到字符串的起始位置用在正则表达式的末尾,表示定位到字符串的结束位置。
这里的知识点基本上是《正则指引》的读书笔记,只是每个知识点的示例代码用php来实现。
1. 字符组字符组的基本用法字符组(Character Class)就是一组字符,在正则表达式中,它表示“在同一个位置可能出现的各种字符”。
写法:[ab]、[314]、[#.?]
[...]
preg_match("/[0123456]/", "5"); // => 1 preg_match("/[abc123]/", "5"); // => 0范围表示法(range)
[x-y]表示x到y整个范围内的字符。如,[0123456789]表示为[0-9],[abcdefghijk]表示为[a-k]。
为什么是[0-9],而不是[9-0]?
因为-表示的范围一般是根据字符对应的码值(Code Point)来确定的。典型地有ACSⅡ编码。在ACSⅡ编码中,0~9的码值是48~57,a~z的码值是97~122,A~Z的码值是65~90。
preg_match("/[0-9]/", "5"); // => 1 preg_match("/[a-z]/", "5"); // => 0 preg_match("/[0-9a-fA-F]/", "0"); // 16进制字符组简记法(shorthands)
提供比范围表示法更简洁的表示方法,如d表示[0-9],w表示[0-9a-zA-z_]。
php中支持的字符组简记:
d 所有的数字,即[0-9]
D 所有的非数字,与d互斥
w 所有的单词字符(字符、数字、下划线),即[0-9a-zA-Z_]
W 所有的非单词字符,与W互斥
s 所有的空白字符,包括空格、制表符、回车符、换行符等空白字符
S 所有的非空白字符,与s互斥
preg_match("/d/", "8"); // => 1 preg_match("/d/", "a"); // => 0 preg_match("/d[a-z]/", "a"); // => 1 preg_match("/w/", "a"); // => 1 preg_match("/w/", "6"); // => 1 preg_match("/w/", "_"); // => 1 preg_match("/s/", " "); // => 1 preg_match("/s/", " "); // => 1 preg_match("/s/", " "); // => 1元字符与转义
在范围表示法中,字符组中的横线-不能匹配横线字符,而是用来表示范围,这类字符叫做元字符(meta-character)。元字符除了-还有开方括号[、闭刚括号]、^、$等,它们都有特殊的意义。
当元字符想要表示普通字符的含义时(如-就只想表示横线字符),就需要转义处理(在元字符前加反斜线字符)。对于-,有一个例外情况,就是当它紧跟着字符组中的开括号[时,它就表示普通横线字符,此时不用转义。
preg_match("/[0-9]/", "-"); // => 1 preg_match("/[0-9]/", "8"); // => 0 preg_match("/[0-9]/", "0"); // => 1 preg_match("/[-09]/", "-"); // => 1 preg_match("/[0-9]/", "-"); // => 1 preg_match("/[0-9]/", "-"); // => 1
仔细看上面第一个表达式和最后两个表示式。这里要注意:
在php中,字符串既可以用单引号标注也可以用双引号标注。两者的主要区别在于,双引号字符串可以插值,二单引号字符串不能;另外,双引号字符串会处理字符串转义,二单引号字符串不会
正则表达式是以字符串的方式提供的。在php中,双引号字符串本身也有关于转义的规定(如""、" "、" "等),因此"0-9"与"0-9"是等价的。
那么最后一个表达式为什么也可以匹配呢?这是因为,尽管php的正则表达式用字符串文字给出,但它与常见的字符串不完全一样——如果某个转义序列可以有字符串识别,则对其进行转义处理;否则,将整个转义序列“原封不动”地保存下来。
因此,在正则表达式中转义要小心,在php中,使用单引号字符串来构建正则表达式会比双引号字符串更简单明了。
排除型字符组(Negated Character Class)在方括号[…]中列出希望匹配的所有字符叫做“普通字符组”。在开方括号[之后紧跟一个脱字符^,写作[^…],表示“在当前位置,匹配一个没有列出的字符”。例如,[^0-9]匹配非数字字符。
preg_match("/[^0-9][0-9]/", "A8"); // => 1
排除型字符组中的紧跟着开方括号[的脱字符^也是元字符,如果要匹配尖括号字符,需要进行转义处理。但是,不紧跟着开方括号[的^就是普通字符,不需要转义。
preg_match("/[^0-9]/", "0"); // => 0 preg_match("/[^0-9]/", "0"); // => 1 preg_match("/[^0-9]/", "^"); // => 1 preg_match("/[0-9^]/", "^"); // => 1POSIX字符组
之前介绍的字符组,都属于Perl衍生出来的正则表达式流派(Flavor),这个流派叫做PCRE(Per Compatible Regular Expression)。正则表达式还有其他流派,比如POSIX(Portable Operating System Interface for unix),它是一系列规范,定义了UNIX操作系统应当支持的功能,其中也包括了正则表达式的规范。
常见的[a-z]形式的字符组,在POSIX规范中仍然获得支持,称作POSIX方括号表达式。POSIX方括号表达式中的不是用来转义的,如[d]就只能匹配和d两个字符。这里涉及到]、-这两个特殊字符,在POSIX规范中,紧接在开方括号[之后的]才表示闭方括号字符,紧挨在闭方括号]之前的-才表示横线字符。
对于PCRE规范中的d、w、s等字符组简记法,POSIX中有类似的东西,叫做POSIX字符组。在ASCⅡ语言环境(locale)中,常见的POSIX字符组及其含义如下:
POSIX字符组 | 说明 | ACSⅡ字符组 | 等价的PCRE简记法 |
---|---|---|---|
[:alnum:] | 字母和数字 | [0-9a-zA-Z] | |
[:alpha:] | 字母 | [a-zA-Z] | |
[:ASCⅡ] | ASCⅡ字符 | [x00-x7F] | |
[:blank:] | 空格字符和制表字符 | [ ] | |
[:cntrl:] | 控制字符 | [x00-x1Fx7F] | |
[:digit:] | 数字字符 | [0-9] | d |
[:graph:] | 空白字符之外的字符 | [x21-x7E] | |
[:lower:] | 小写字母字符 | [a-z] | |
[:print:] | 类似[:graph:],但包括空白字符 | [x20-x7E] | |
[:punct:] | 标点符号 | [][!"#$%&"()*+,./:;<=>?@^_`{ | }~-] |
[:space:] | 空白字符 | [ vf] | s |
[:upper:] | 大写字母 | [A-Z] | |
[:word:] | 字母字符 | [A-Za-z0-9_] | w |
[:xdigit:] | 十六进制字符 | [A-Fa-f0-9] |
php中有专门处理POSIX正则的函数,但从5.3.0开始已经废弃了。这里只是了解一下相关知识。
2. 量词这里首先介绍一下^和$两个特殊字符,在上一章的元字符与转义一节提到过这两个特殊字符。
^放在正则表达式的开头,表示“定位到字符串的起始位置”;$用在正则表达式的末尾,表示“定位到字符串的结束位置”。
preg_match("/wd/", "1a2b"); // => 1 preg_match("/^wd/", "1a2b"); // => 0 必须以字母开头 preg_match("/wd$/", "1a2b"); // => 0 必须以数字结尾 preg_match("/^wd/", "a2b"); // => 1 preg_match("/wd$/", "1a2"); // => 1 preg_match("/^wd$/", "1a2"); // => 0 开头必须是字母,结尾必须是数字 preg_match("/^wd$/", "a2"); // => 1量词的一般形式
如果要匹配一个邮政编码(6位数字),目前能写出来的正则表达式是^ffffdffffd$:
preg_match("/^ffffdffffd$/", "100010"); // => 1 preg_match("/^ffffdffffd$/", "10001035"); // => 0 preg_match("/^ffffdffffd$/", "10a010"); // => 0
d重复6次的写法很不科学,正则表达式肯定会有更方便的写法,也就是量词(quantifier)。量词的通用形式是{m,n}(注意,,后面不能有空格),它限定之前的元素能够出现的次数,m是下限,n是上限。其他常见的量词形式有:
量词 | 说明 |
---|---|
{n} | 之前的元素必须出现n次 |
{m,n} | 之前的元素最少出现m次,最多出现n次 |
{m,} | 之前的元素最少出现m次,出现次数无上限 |
{0,n} | 之前的元素可以不出现,也可以出现,最多出现n次 |
preg_match("/^d{6}$/", "100010"); // => 1 preg_match("/^d{4,6}$/", "123"); // => 0 preg_match("/^d{4,6}$/", "1234"); // => 1 preg_match("/^d{4,6}$/", "123456"); // => 1 preg_match("/^d{4,6}$/", "1234567"); // => 0常用量词
正则表达式还有三个常用的量词,分别是+、?、*:
常用量词 | {m,n}等价形式 | 说明 |
---|---|---|
* | {0,} | 可能出现,也可能不出现,出现次数没有上限 |
+ | {1,} | 至少出现1次,出现次数没有上限 |
? | {0,1} | 出现0次或1次 |
这三种量词在实际中使用的非常多。
例如,匹配url的时候,有可能是http,也有可能是https,这个时候用?就很方便:
preg_match("/^https?://www.baidu.com/", "http://www.baidu.com"); // => 1 preg_match("/^https?://www.baidu.com/", "https://www.baidu.com"); // => 1
在匹配html的tag(如、 <(?!/).*+(? 上面的正则表达式中有两个环视结构,一个在开尖括号<之后,表示在尖括号<后向右看看,右边的第一个字符不能为/(正则表达式中进行了转义);另外一个在闭尖括号>之前,表示在闭尖括号>之前向左看看,左边挨着的字符不能为/。 上面的正则表达式已经解决了匹配html中开标签的主要问题,只是其中的.*?还需要优化一下。需要解决的问题是: 有可能会有单引号"或双引号",它们都得成对出现 单引号对或双引号对之内可以有>字符,但是它们的外面不能有>字符 利用正则表达式的选择结构,可以写出下面的表达式,用于完善上面的问题。 <(?!/)(?:"[^"]*"|"[^"]*"|[^"">])+(? 前面的内容中已经出现介过了单行模式、多行模式、非贪婪模式。匹配模式是指匹配时使用的规则。常用的匹配模式还有不区分大小写模式、注释模式。 在开始介绍具体的模式之前,先介绍php中模式的两种具体实现/.../{modifier}和...(?{modifier})...: 在html中是不区分大小写的,例如 <[tT][dD]> 由于 / 形式:/.../s或...(?s)... 与单行模式没有关系。影响^和$的匹配 (?#...)的方法可以在正则表达式中添加注释 更彻底地,可是使用/.../x表示注释模式 要匹配中文等Unicode字符,最好是指定Unicode模式修饰符/.../u。如果不指定会有两个问题 GBK编码环境下,中文不能匹配 无法利用[x{4e00}-x{9fff}]匹配中文 文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。 转载请注明本文地址:https://www.ucloud.cn/yun/21135.html 摘要:一正则表达式函数解析表单验证等地址的合法性匹配结果可以看作是值非法词的过滤二正则表达式基本语法测试正则表达式的工具中午匹配最好转成转换工具注意是必须在一起的,否则如下也被当成一个原子去匹配。
一、PHP正则表达式函数解析
showImg(https://segmentfault.com/img/bVThUH?w=638&h=95);
showImg(https://segmentfau... 摘要:是决定正则表达式匹配规则的主要部分。二分隔符分隔符的选择当使用函数的时候,正则表达式必须由分隔符闭合包裹。果分隔符经常在正则表达式内出现,最好使用其他分隔符来提高可读性。需要将一个字符串放入正则表达式中使用时,可以用函数对其进行转义。
一、简介
1. 什么是正则表达式
正则表达式(Regular Expression)就是用某种模式去匹配一类字符串的一种公式。正则表达式使用单个字符串来... 摘要:在阅读这篇文章前最好把同系列文章实战正则表达式一验证手机号先仔细阅读一遍。但实际上这样一个表达式是无法从上面的中提取第一个元素的这里主要的问题是在默认情况下点号字符无法匹配换行符。但是很遗憾,正则表达式中没有排除型子表达式或者说排除型分组。
这篇文章通过提取html元素介绍了正则表达式中模式修饰符、贪婪匹配与非贪婪匹配、Unicode模式、环视等知识点。在阅读这篇文章前最好把同系列文章... 摘要:兼容的正则表达式已经实现了很多使用不同解析引擎的正则函数。中主要有两个正则解析器一个称为,另一个称为兼容正则表达式。在中,每个正则表达式模式都是使用符合格式的字符串。
原文链接: Getting Started with PHP Regular Expressions
Last-Modified: 2019年5月10日16:23:19译者注:
本文是面向0正则基础的phper, 很多... 阅读 3728·2021-11-24 09:39 阅读 2609·2019-08-30 15:54 阅读 1148·2019-08-30 13:01 阅读 3428·2019-08-28 18:30 阅读 1622·2019-08-26 17:44 阅读 3590·2019-08-26 11:31 阅读 2412·2019-08-26 10:40 阅读 1239·2019-08-26 10:27
直接使用<[^/]+>将/字符排除是不对的,因为有些标签的属性中可能会含有/字符。例如。这里只是在开尖括号<之后的第一个字符和闭尖括号>之前的第一个字符不能为/。
然而<[^/][^>]*[^/]>也是不行的,因为在<与>之间会至少匹配两个字符,像这样的标签是无法匹配到的。这里就要用到环视了。
不区分大小写模式
模式修饰符
/.../{modifier}
...(?{modifier})...
示例
/
.* /s(?s).*
名称(php手册)
模式修饰符
模式内修饰符
名称(《正则指引》)
预定义常量
模式修饰符
作用范围
整个正则表达式
不在分组(子表达式)中时,对它后面的全部正则表达式起作用;如果在分组(子表达式)中,则对它分组中的剩余部分起作用。在没有分组,且放在整个正则表达式最前面的时候相当于/.../{modifier}
支持程度
支持所有模式修饰符
支持部分模式修饰符
其他编程语言
可能不支持
一般都支持
和 、 、 的作用是一样的。如果要从网页中提取 ,不使用匹配模式的表达式应该是这样:
标签只有两个字符,所以上面的写法还可以接受。但是如果标签是呢?这里,就需要使用不区分大小写模式:/.../i或...(?i)...。上面的正则表达式可以进一步写为:
/i或(?i)
preg_match("/(?i)
/", " ", $arr);
print_r($arr);
/*
Array
(
[0] =>
)
*/
单行模式
作用:点号可以匹配换行符
形式:/.../x或...(?m)...// (?#...)注释
preg_match("/(?#this is comment)(?i)
/", " ", $arr);
print_r($arr);
/*
Array
(
[0] =>
)
*/
// /.../x注释模式
$str = "/
(d{4}) # year
- # dash
(d{2}) # month
- # dash
(d{2}) # day
/x";
preg_match($str, "2015-10-01", $arr);
print_r($arr);
/*
Array
(
[0] => 2015-10-01
[1] => 2015
[2] => 10
[3] => 01
)
*/
非贪婪
// 默认贪婪匹配
$str = "
Unicode
hello ";
preg_match("/world .* /", $str, $arr);
print_r($arr);
/*
Array
(
[0] => hello
)
*/
// 非贪婪匹配模式
$str = "world hello ";
preg_match("/world .* /U", $str, $arr);
print_r($arr);
/*
Array
(
[0] =>
)
*/hello // 指定unicode模式
preg_match("/
[x{4e00}-x{9fff}]* /u", "姚明 ", $arr);
print_r($arr);
/*
Array
(
[0] => 姚明
)
*/相关文章
PHP正则表达式函数解析与正则表达式基本语法
搞定PHP面试 - 正则表达式知识点整理
php实战正则表达式(二):提取html元素
PHP 正则表达式入门 Getting Started with PHP Regular Expre
发表评论
0条评论
lunaticf
男|高级讲师
TA的文章
阅读更多
集成 nacos注册中心配置使用
html+css布局类型
【二次元的CSS】—— 用 DIV + CSS3 画大白(详解步骤)
扒一下W3C规范里的BFC和IFC
element ui table render-header自定义表头信息使用
JS中的面向对象编程
面向切面编程与装饰器
常用的几个编码风格规范