0

0

如何在PHP中将字符串按正则模式分割成数组?preg_split实例

蓮花仙者

蓮花仙者

发布时间:2025-08-27 12:28:01

|

515人浏览过

|

来源于php中文网

原创

preg_split适用于复杂分隔符,支持正则表达式、去除空值、捕获分隔符及限制分割次数,而explode仅支持固定字符串分隔;当分隔需求涉及多种字符或模式时,应选择preg_split以提升灵活性和效率。

如何在php中将字符串按正则模式分割成数组?preg_split实例

在PHP中,如果你需要根据一个复杂的模式,也就是正则表达式,来将字符串拆分成数组,那么

preg_split
函数无疑是你的首选工具。它提供了远超
explode
的灵活性,能够处理多变的分隔符、空字符串的去除,甚至捕获分隔符本身。

preg_split
是PHP处理字符串分割的利器,尤其当分隔符不再是简单的固定字符,而是需要通过正则表达式来定义时。它的基本用法非常直观,但其内部的参数组合却能解锁强大的功能。

 apple
    [1] => orange
    [2] => banana
    [3] => grape
)
*/

// 示例2:去除结果中的空字符串
// 比如我们想分割 "a,,b",如果不用PREG_SPLIT_NO_EMPTY,会得到 ["a", "", "b"]
$empty_string_text = "item1,,item2, item3";
$items_with_empty = preg_split('/,/', $empty_string_text);
print_r($items_with_empty);

/*
输出:
Array
(
    [0] => item1
    [1] =>
    [2] => item2
    [3] =>  item3
)
*/

// 使用PREG_SPLIT_NO_EMPTY旗标,可以有效避免这种“意外”的空值
$items_no_empty = preg_split('/,/', $empty_string_text, -1, PREG_SPLIT_NO_EMPTY);
print_r($items_no_empty);

/*
输出:
Array
(
    [0] => item1
    [1] => item2
    [2] =>  item3
)
*/

// 示例3:捕获分隔符
// 有时候,我们不仅想分割,还想知道是用什么分割的
$log_entry = "User:Alice-Action:Login-Time:2023-10-27";
$parts_with_delimiters = preg_split('/(:|-)/', $log_entry, -1, PREG_SPLIT_DELIM_CAPTURE);
print_r($parts_with_delimiters);

/*
输出:
Array
(
    [0] => User
    [1] => :
    [2] => Alice
    [3] => -
    [4] => Action
    [5] => :
    [6] => Login
    [7] => -
    [8] => Time
    [9] => 2023-10-27
)
*/

// 示例4:限制分割次数
// 假设我们只想分割前两次,其余部分保持不变
$full_path = "/home/user/documents/report.txt";
$limited_parts = preg_split('/\//', $full_path, 3); // 限制分割为最多3个元素
print_r($limited_parts);

/*
输出:
Array
(
    [0] =>
    [1] => home
    [2] => user/documents/report.txt
)
*/

// 注意:如果字符串以分隔符开始,第一个元素会是空字符串,除非你用了PREG_SPLIT_NO_EMPTY。
// 我觉得这一点在实际开发中挺容易被忽略的,得留心。

?>

preg_split与explode有何不同?何时选择正则分割?

这真的是个老生常谈的问题了,但每次讨论到字符串分割,总会有人问起。简单来说,

explode
函数只能用一个固定的字符串作为分隔符来分割字符串。比如你想按逗号分割,它就只认逗号。而
preg_split
则强大得多,它能接受一个正则表达式作为分隔符模式。这意味着你可以按“一个或多个空格”、“逗号或分号”、“任何非字母数字字符”等等复杂的规则来分割。

在我看来,选择哪个函数,主要看你的“分隔符”有多复杂。 如果你的分隔符是固定的,比如总是用逗号

,
,或者总是用管道符
|
,那么
explode
会是更高效、更简洁的选择。它的性能通常比
preg_split
好,因为不需要解析正则表达式。

但是,一旦你的需求变得稍微复杂一点,比如:

立即学习PHP免费学习笔记(深入)”;

  • 多重分隔符: 你想同时按逗号、分号和空格来分割。
    explode
    就无能为力了,你可能得写好几层
    str_replace
    或者循环,那简直是灾难。这时候
    preg_split
    一个模式
    '/[;, ]+/'
    就能搞定。
  • 可变分隔符: 比如你可能需要按“一个或多个空白字符”来分割,而不仅仅是一个空格。
    explode
    只能按一个空格分割,多余的空格会生成空字符串或者额外的元素。
    preg_split
    /\s+/
    模式则能完美处理。
  • 需要忽略空匹配: 当分隔符连续出现时,
    explode
    会生成空字符串。如果你不希望结果数组中有这些空字符串,
    preg_split
    配合
    PREG_SPLIT_NO_EMPTY
    旗标就非常方便。

所以,我的经验是,能用

explode
就用
explode
,简单高效;一旦发现
explode
力不从心,需要更灵活的匹配模式,就果断切换到
preg_split
。别硬着头皮用
explode
去模拟正则行为,那样只会让代码变得臃肿且难以维护。

如何利用preg_split的flags参数精细控制分割行为?

preg_split
flags
参数是我觉得它真正强大之处,它能让你对分割过程有非常细致的控制。了解并善用这些旗标,可以解决很多实际开发中遇到的痛点。

Play.ht
Play.ht

根据文本生成多种逼真的语音

下载

最常用的几个旗标包括:

  1. PREG_SPLIT_NO_EMPTY
    : 这个旗标的作用是,如果分割结果中出现了空字符串,就把它从最终的数组中移除。这在处理用户输入或者解析一些不规范的文本时特别有用。比如,你可能有一个字符串
    "a,,b"
    ,如果按逗号分割,默认会得到
    ["a", "", "b"]
    。但通常我们不想要那个空的元素。加上
    PREG_SPLIT_NO_EMPTY
    后,结果就成了
    ["a", "b"]
    。这大大简化了后续的数据处理步骤,避免了额外的
    array_filter
    操作。

  2. PREG_SPLIT_DELIM_CAPTURE
    : 这个旗标就有点意思了,它能让你的正则表达式中,所有被捕获的分组(也就是用括号
    ()
    括起来的部分)也作为结果数组的一部分被返回。这对于需要分析分隔符类型或上下文的场景非常有用。比如,如果你按
    /(,|;)/
    分割,不仅会得到被分割的片段,还会得到每个片段之间的逗号或分号。这在日志分析、协议解析等场景下,能帮助你更好地理解数据结构。

  3. PREG_SPLIT_OFFSET_CAPTURE
    : 这个旗标相对来说用得少一些,但一旦需要,它就能提供关键信息。它会让结果数组中的每个元素都变成一个子数组,其中包含两个值:第一个是被分割的字符串片段,第二个是该片段在原始字符串中的字节偏移量(起始位置)。这对于需要知道每个片段在原文中具体位置的场景(比如语法高亮、错误定位)非常有用。它能让你在处理完分割结果后,还能追溯到原始字符串的上下文。

在我看来,

PREG_SPLIT_NO_EMPTY
几乎是
preg_split
的标配,因为它能有效清理掉那些无意义的空元素。而
PREG_SPLIT_DELIM_CAPTURE
PREG_SPLIT_OFFSET_CAPTURE
则属于“特殊任务”型的旗标,当你遇到特定需求时,它们能提供独一无二的解决方案。

处理复杂场景:多重分隔符与捕获组的进阶应用

当我们谈论

preg_split
的进阶应用时,往往就离不开更复杂的正则表达式模式。这不仅仅是把几个分隔符简单地用
|
连接起来,更涉及到如何精确匹配、如何利用捕获组来提取额外信息,甚至是一些性能上的考量。

1. 应对多重分隔符与变长空白: 最常见的复杂场景之一就是处理那些“不规矩”的文本,比如用户输入。用户可能用逗号、分号、甚至多个空格来分隔列表项。一个简单的

preg_split('/[,;\s]+/', $text, -1, PREG_SPLIT_NO_EMPTY);
就能很好地解决这个问题。这里的
\s+
匹配一个或多个空白字符,
[,;]
匹配逗号或分号。组合起来,就能灵活地处理各种分隔情况,同时避免空元素。

2. 包含或排除特定分隔符: 有时候,我们希望分割,但又不想把某些特定的分隔符也丢弃。例如,我们想按“AND”或“OR”分割一个查询字符串,但这些词本身可能也是有意义的。

$query = "tag1 AND tag2 OR tag3";
// 如果我们只是简单地分割,AND和OR就没了
$parts = preg_split('/(AND|OR)/', $query, -1, PREG_SPLIT_NO_EMPTY);
print_r($parts);
/*
Array
(
    [0] => tag1
    [1] =>  tag2
    [2] =>  tag3
)
*/

// 但如果结合PREG_SPLIT_DELIM_CAPTURE,我们就能同时得到分隔符和内容
$parts_with_ops = preg_split('/(AND|OR)/', $query, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($parts_with_ops);
/*
Array
(
    [0] => tag1
    [1] => AND
    [2] =>  tag2
    [3] => OR
    [4] =>  tag3
)
*/

这样,我们就能在处理逻辑时,清楚地知道每个操作符是什么,这在构建解析器或查询引擎时非常关键。

3. 避免过度贪婪匹配与回溯问题: 在使用复杂的正则表达式时,尤其是涉及到量词(

+
,
*
)和捕获组时,要警惕正则表达式的“贪婪”特性。默认情况下,量词会尽可能多地匹配字符。如果模式写得不好,可能会导致意料之外的匹配结果,甚至引发“回溯”问题,影响性能。

例如,如果你想分割由特定前缀和后缀包围的字符串,但前缀和后缀可能出现在多个位置:

$str = "START item1 END START item2 END";
如果用
preg_split('/START(.*?)END/', $str)
来尝试分割,并期望得到
item1
item2
,这可能不是
preg_split
的最佳用法,因为它更侧重于删除分隔符。在这种情况下,
preg_match_all
配合非贪婪匹配
.*?
可能更合适用来提取内容。

所以,在设计

preg_split
的正则表达式时,我的建议是:

  • 保持简洁: 尽量让模式只匹配你需要作为分隔符的部分。
  • 测试: 使用在线正则表达式工具(如regex101.com)充分测试你的模式,确保它能正确匹配你期望的分隔符,并且不会意外匹配到其他内容。
  • 性能考量: 对于非常长的字符串或在循环中频繁调用
    preg_split
    ,过于复杂的正则表达式可能会影响性能。在这种情况下,可以考虑是否能通过预处理字符串(如
    str_replace
    )简化分隔符,然后再用简单的
    preg_split
    explode

总的来说,

preg_split
的强大在于它的灵活性,但这种灵活性也要求我们对正则表达式有足够的理解和实践。掌握好这些进阶技巧,能让你在处理各种复杂的字符串分割任务时游刃有余。

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2649

2023.09.01

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

1657

2023.10.11

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

1515

2023.10.11

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

952

2023.10.23

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

1418

2023.10.23

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

1234

2023.11.03

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1468

2023.11.09

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

1306

2023.11.13

高德地图升级方法汇总
高德地图升级方法汇总

本专题整合了高德地图升级相关教程,阅读专题下面的文章了解更多详细内容。

72

2026.01.16

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
进程与SOCKET
进程与SOCKET

共6课时 | 0.3万人学习

Swoft2.x速学之http api篇课程
Swoft2.x速学之http api篇课程

共16课时 | 0.9万人学习

php初学者入门课程
php初学者入门课程

共10课时 | 0.6万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号