搜索
首页后端开发php教程php实战正则表达式(二):提取html元素

这篇文章通过提取html元素介绍了正则表达式中模式修饰符、贪婪匹配与非贪婪匹配、Unicode模式、环视等知识点。
在阅读这篇文章前最好把同系列文章php实战正则表达式(一):验证手机号先仔细阅读一遍。

基本提取

有这样一个表格

用户名 职业
Kobe Bryant 篮球运动员
Jay Chou 歌手、词曲创作人、制作人、演员、导演
Lionel Messi 足球运动员

它的源码如下:

<table>  <thead>    <tr><th>用户名</th><th>职业</th></tr>  </thead>  <tbody>    <tr>      <td>Kobe Bryant</td><td>篮球运动员</td>    </tr>    <tr>      <td>Jay Chou</td><td>歌手、词曲创作人、制作人、演员、导演</td>    </tr>    <tr>      <td>Lionel Messi</td><td>足球运动员</td>    </tr>  </tbody></table>

现在要提取

第一个元素。最简单的正则表达式应该是这样:

\s+.*

其中

  • \s是php实战正则表达式(一):验证手机号介绍过的字符组简记法中的一个,代表回车符、空格、制表符等空白字符

  • 量词+表示它所修饰的字符或字符组出现次数大于等于1

  • 点号字符.在正则表达式中是一个特殊的元字符,它可以匹配“任意字符”

  • 闭标签

中的斜线/在php的正则表达式中是模式分隔符,所以需要转义来表示斜线字符。

但实际上这样一个表达式是无法从上面的

中提取第一个元素的

这里主要的问题是在默认情况下点号字符.无法匹配换行符\n。有两个方法可以解决这个问题:

  • 使用模式修饰符s,正则表达式为/

    \s+.*/s或(?s) \s+.*。模式修饰符s的作用就是让点号字符.可以匹配换行符。
  • 用[\s\S]或[\w\W]或[\d\D]代替点号字符.来匹配所有字符,正则表达式为

    \s+[\s\S]*

    关于模式修饰符(Pattern Modifiers),这里需要详细介绍一下(点击这里查看php支持的所有模式修饰符)。模式修饰符可以改变正则表达式的一些默认规则,常用的模式修饰符有i、s、U、u等,我们在后面会用到它们中的一些,这里不展开介绍每个模式修饰符的作用,后面用到了再具体介绍。这里主要对比一下/.../{modifier}与...(?{modifier})...两种表示方法的区别。

    .*/s (?s).*
    模式修饰符 /.../{modifier} ...(?{modifier})...
    示例 /
    名称(php手册) 模式修饰符 模式内修饰符
    名称(《正则指引》) 预定义常量 模式修饰符
    作用范围 整个正则表达式 不在分组(子表达式)中时,对它后面的全部正则表达式起作用;如果在分组(子表达式)中,则对它分组中的剩余部分起作用。在没有分组,且放在整个正则表达式最前面的时候相当于/.../{modifier}
    支持程度 支持所有模式修饰符 支持部分模式修饰符
    其他编程语言 可能不支持 一般都支持

    从上面的gif中可以看到提取的结果中有三个tr,而不是只有一个。这是因为正则表达式中量词默认是贪婪匹配,在这里,.*会匹配一切字符,直到最后没有字符再向前回溯,回溯到

    中的最后一个时与正则表达式中的相匹配,从而完成整个匹配过程,最后的结果也就是包含了三个。

    可以使用模式修饰符U指定整个正则表达式为非贪婪模式,也可以使用非贪婪匹配量词指定某一个量词为非贪婪模式:

    • 指定整个正则表达式为非贪婪模式:

      • /

        \s+.*/Us
      • 或(?Us)

        \s+.*
      • 非贪婪量词:
        /

        \s+.*?/s

        完整的贪婪量词(匹配优先量词)与非贪婪量词(忽略优先量词)见下表:

        贪婪量词 非贪婪量词 限定次数
        * *? 可能出现,可能不出现,出现次数没有上限
        + +? 至少出现1次,没有上限
        ? ?? 出现0次或1次
        {m,n} {m,n}? 出现次数大于等于m,小于等于n
        {m,} {m,}? 至少出现m次,没有上限
        {0,n} {0,n}? 出现0次-n次

        提取包含指定内容的行

        假设我们想把表格中有关于运动员的记录都提取出来,我们可能会使用/

        .*运动员.*/s这样的正则表达式。

        这个表达式在Unicode编码环境下可以匹配出结果,但是在GBK环境下就未必了。我们可以通过模式修饰符u来指定Unicode模式:

        /

        .*运动员.*/us

        在Unicode模式下,我们甚至可以使用码值来代替汉字:

        /

        .*\x{8fd0}\x{52a8}\x{5458}.*/us

        php正则中使用\x{hex}的形式来表示Unicode字符的码值,使用码值的好处是可以结合字符组来表示一段范围,如[\x{4e00}-\x{9fff}]表示匹配所有汉字字符。

        上面的表达式可以匹配出结果,但是却不正确。我们可以看到,它匹配了整个字符串的第一个

        到最后一个。
        直觉上,我们是想正则表达式先去匹配“运动员”,然后向左寻找最近的一个,向右寻找最近的一个。但事实上,正则表达式是从左往右匹配的,即从开始寻找,整个正则表达式的匹配情况见下表(空白字符没有显示出来)。
        表达式 匹配值
        /
        .* 用户名 职业
        Kobe Bryant 篮球
        运动员 运动员
        .*
        Jay Chou 歌手、词曲创作人、制作人、演员、导演
        Lionel Messi 足球运动员
        /us

        这里两个.*匹配到的字符都比预期要多。第二个.*匹配字符比预期多的原因是正则表达式默认是贪婪匹配模式,它会匹配剩余字符串中的每个字符,直到字符串的末尾,然后再向前回溯到最后一个

        ,可以通过指定非贪婪匹配模式来解决这个问题。但是第一个.*匹配字符比预期多是正常现象,因为正则表达式是从左向右匹配的,表达式中的匹配字符串中第一个 ,后面的.*则匹配剩余的所有字符,直到字符串的末尾,然后再向前回溯到“运动员”。

        我们先看看使用非贪婪匹配时的结果:

        可以看到,第二个.*匹配的字符已经是我们想要的了。那么,对于第一个.*匹配字符比预期多这个问题怎么解决呢?

        如果仅使用到目前为止我的文章中介绍的知识,也是有方法可以解决的。我们可以先从左到右匹配出所有的行(

        ...),方法是使用php中的preg_match_all函数结合非贪婪匹配模式;然后再遍历每一行,过滤出其中包含“运动员”的行即可。

        当然,我们也可以通过纯粹的正则表达式来解决这个问题。如果有一定正则表达式使用经验的朋友可能很容易联想到排除型字符组,我们介绍过字符组[...],它表示在同一位置可能出现的字符。而排除型字符组则表示在同一位置不能出现的字符,它的形式是[^...],通过紧跟在开方括号[后面的^来表示排除型字符组。例如,[^\d]表示匹配的字符是除了数字以外的任意字符。
        如果有排除型子表达式,类似于(^

        )*,我们只需要指定第一个.*把 排除就行了。但是很遗憾,正则表达式中没有排除型子表达式或者说排除型分组。这种情况下,我们只能使用环视

        /

        (.(?! ))*运动员.*/Us

        环视(look-around)不匹配任何字符,用来“停在原地,四处张望”。上面的表达式使用了否定顺序环视,它的形式是(?!...)。具体对于(.(?!

        ))*来分析,每当.匹配了一个字符后,就向右看看,如果当前匹配字符的右边没有出现 就匹配成功。

        完整的环视有:

        名字 记法 含义
        肯定顺序环视 (?=...) 向右看看,右边出现了环视中的内容才匹配
        否定顺序环视 (?!...) 向右看看,右边不出现环视中的内容才匹配
        肯定逆序环视 (? 向左看看,左边出现了环视中的内容才匹配
        否定逆序环视 (? 向左看看,左边不出现环视中的内容才匹配

        由于上面的正则表达式有一个分组(子表达式),所以匹配的结果除了下标0,还有下标1,这里下标1的结果其实没有什么用,我们可以用之前介绍过的非捕获分组

        /

        (?:.(?! ))*运动员.*/Us

        我们的真正目的是提取所有包含“运动员”的行,而上面只提取了第一个,所以需要将preg_match函数换成preg_match_all。

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
11个最佳PHP URL缩短脚本(免费和高级)11个最佳PHP URL缩短脚本(免费和高级)Mar 03, 2025 am 10:49 AM

长URL(通常用关键字和跟踪参数都混乱)可以阻止访问者。 URL缩短脚本提供了解决方案,创建了简洁的链接,非常适合社交媒体和其他平台。 这些脚本对于单个网站很有价值

Instagram API简介Instagram API简介Mar 02, 2025 am 09:32 AM

在Facebook在2012年通过Facebook备受瞩目的收购之后,Instagram采用了两套API供第三方使用。这些是Instagram Graph API和Instagram Basic Display API。作为开发人员建立一个需要信息的应用程序

在Laravel中使用Flash会话数据在Laravel中使用Flash会话数据Mar 12, 2025 pm 05:08 PM

Laravel使用其直观的闪存方法简化了处理临时会话数据。这非常适合在您的应用程序中显示简短的消息,警报或通知。 默认情况下,数据仅针对后续请求: $请求 -

构建具有Laravel后端的React应用程序:第2部分,React构建具有Laravel后端的React应用程序:第2部分,ReactMar 04, 2025 am 09:33 AM

这是有关用Laravel后端构建React应用程序的系列的第二个也是最后一部分。在该系列的第一部分中,我们使用Laravel为基本的产品上市应用程序创建了一个RESTFUL API。在本教程中,我们将成为开发人员

简化的HTTP响应在Laravel测试中模拟了简化的HTTP响应在Laravel测试中模拟了Mar 12, 2025 pm 05:09 PM

Laravel 提供简洁的 HTTP 响应模拟语法,简化了 HTTP 交互测试。这种方法显着减少了代码冗余,同时使您的测试模拟更直观。 基本实现提供了多种响应类型快捷方式: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

php中的卷曲:如何在REST API中使用PHP卷曲扩展php中的卷曲:如何在REST API中使用PHP卷曲扩展Mar 14, 2025 am 11:42 AM

PHP客户端URL(curl)扩展是开发人员的强大工具,可以与远程服务器和REST API无缝交互。通过利用Libcurl(备受尊敬的多协议文件传输库),PHP curl促进了有效的执行

在Codecanyon上的12个最佳PHP聊天脚本在Codecanyon上的12个最佳PHP聊天脚本Mar 13, 2025 pm 12:08 PM

您是否想为客户最紧迫的问题提供实时的即时解决方案? 实时聊天使您可以与客户进行实时对话,并立即解决他们的问题。它允许您为您的自定义提供更快的服务

宣布 2025 年 PHP 形势调查宣布 2025 年 PHP 形势调查Mar 03, 2025 pm 04:20 PM

2025年的PHP景观调查调查了当前的PHP发展趋势。 它探讨了框架用法,部署方法和挑战,旨在为开发人员和企业提供见解。 该调查预计现代PHP Versio的增长

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

AI Hentai Generator

AI Hentai Generator

免费生成ai无尽的。

热门文章

R.E.P.O.能量晶体解释及其做什么(黄色晶体)
2 周前By尊渡假赌尊渡假赌尊渡假赌
仓库:如何复兴队友
4 周前By尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island冒险:如何获得巨型种子
4 周前By尊渡假赌尊渡假赌尊渡假赌

热工具

Dreamweaver CS6

Dreamweaver CS6

视觉化网页开发工具

SecLists

SecLists

SecLists是最终安全测试人员的伙伴。它是一个包含各种类型列表的集合,这些列表在安全评估过程中经常使用,都在一个地方。SecLists通过方便地提供安全测试人员可能需要的所有列表,帮助提高安全测试的效率和生产力。列表类型包括用户名、密码、URL、模糊测试有效载荷、敏感数据模式、Web shell等等。测试人员只需将此存储库拉到新的测试机上,他就可以访问到所需的每种类型的列表。

安全考试浏览器

安全考试浏览器

Safe Exam Browser是一个安全的浏览器环境,用于安全地进行在线考试。该软件将任何计算机变成一个安全的工作站。它控制对任何实用工具的访问,并防止学生使用未经授权的资源。

EditPlus 中文破解版

EditPlus 中文破解版

体积小,语法高亮,不支持代码提示功能

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),