如何用PHP将字符串按特定模式转为数组?正则表达式技巧

preg_split()通过正则表达式实现复杂字符串分割,支持多分隔符、捕获分隔符及去除空元素,适用于不规则分隔场景,而explode()仅支持固定字符串分隔且性能更高,适合简单分割需求。

如何用php将字符串按特定模式转为数组?正则表达式技巧

PHP里,要把字符串按照特定模式拆分成数组,

preg_split()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

函数就是那个你需要的瑞士军刀。它远比简单的字符分割要强大,能让你用正则表达式来定义任何你想象得到的复杂分隔符。

解决方案:
说实话,当我们遇到需要按复杂规则拆分字符串时,比如不规则的空白、多个不同的分隔符,或者需要跳过某些特定内容时,

explode()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

就显得力不从心了。这时,

preg_split()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

就成了我们的不二之选。它的核心思想是,你告诉我一个正则表达式模式,它就用这个模式去匹配字符串中的“分隔符”,然后把匹配到的部分“切掉”,剩下的就是数组元素了。

最基本的用法是这样:

<?php
$str = "苹果,香蕉;橙子 葡萄";
// 按照逗号、分号或空格来分割
$array = preg_split('/[,;/s]+/', $str);
print_r($array);
/*
输出:
Array
(
    [0] => 苹果
    [1] => 香蕉
    [2] => 橙子
    [3] => 葡萄
)
*/

$str2 = "  你好   世界  PHP  ";
// 匹配一个或多个空白字符作为分隔符,并忽略空元素
$array2 = preg_split('//s+/', $str2, -1, PREG_SPLIT_NO_EMPTY);
print_r($array2);
/*
输出:
Array
(
    [0] => 你好
    [1] => 世界
    [2] => PHP
)
*/
?>
登录后复制
preg_split()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

函数有四个参数:

  1. $pattern
    登录后复制

    :这就是你的正则表达式,定义了分隔符的模式。

  2. $subject
    登录后复制

    :要被分割的字符串。

  3. $limit
    登录后复制

    (可选):限制返回的子字符串数量。如果设置了,最后一个元素会包含字符串的剩余部分。默认是-1,表示没有限制。

  4. $flags
    登录后复制

    (可选):一些位掩码标志,比如

    PREG_SPLIT_NO_EMPTY
    登录后复制
    登录后复制

    (不返回空字符串)或

    PREG_SPLIT_DELIM_CAPTURE
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    (捕获分隔符)。

我个人觉得,真正让

preg_split()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

出彩的,是它对正则表达式的支持。这意味着你可以定义非常精细的分割逻辑,远超单一字符或简单字符串的限制。

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

在PHP中,

preg_split()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

explode()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

函数的主要区别和适用场景是什么?

嗯,这是一个老生常谈的问题,但确实很重要。很多初学者会搞混或者不知道什么时候用哪个。简单来说,

explode()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

就像一把菜刀,只能用固定的刀刃(一个字符串)去切东西;而

preg_split()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

则像一把激光刀,你可以随意调整光束的形状和强度(正则表达式),切割方式灵活得多。

explode()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

的特点:

  • 简单直接: 它只接受一个字符串作为分隔符。
  • 速度快: 在处理大量数据且分隔符固定简单时,

    explode()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    通常比

    preg_split()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    快得多,因为它不需要解析正则表达式。

  • 适用场景: 当你的分隔符是一个固定不变的字符或字符串时,比如 CSV 文件中的逗号,或者日志文件中的特定分隔符。

    <?php
    $data = "item1,item2,item3";
    $items = explode(',', $data); // 非常高效
    print_r($items);
    ?>
    登录后复制

preg_split()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

的特点:

  • 强大灵活: 接受正则表达式作为分隔符,这意味着你可以匹配任何复杂的模式,比如“一个或多个空格”、“数字后面跟着冒号”、“任意标点符号”等等。
  • 功能丰富: 支持各种标志,可以控制空元素的去除、分隔符的捕获等。
  • 性能开销: 由于需要解析和执行正则表达式,它通常比

    explode()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    慢,尤其是在简单的分割任务上。

  • 适用场景: 当分隔符不固定、有多种可能、或者需要忽略一些空白字符、甚至是根据某种逻辑模式来分割时,

    preg_split()
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    就是你的唯一选择。比如,从一段混合文本中提取出所有单词,忽略所有标点和多余的空格。

我的经验是,如果

explode()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

能搞定,就用

explode()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

。如果搞不定,或者你预见到未来可能会有更复杂的分割需求,那就直接上

preg_split()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

,一步到位。没必要为了那一点点理论上的性能差异,去写一个冗长且容易出错的

str_replace()
登录后复制

strtok()
登录后复制

组合。

如何利用

preg_split()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

PREG_SPLIT_DELIM_CAPTURE
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

标志来保留分隔符?

有时候,我们不仅想把字符串拆开,还想知道“是在哪里拆开的”,也就是想把那些作为分隔符的字符也一并捕获到数组里。

PREG_SPLIT_DELIM_CAPTURE
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

这个标志就是为此而生的。它会把正则表达式中捕获组(也就是用括号

()
登录后复制

括起来的部分)匹配到的分隔符也作为数组元素返回。

我们来看个例子:

<?php
$logEntry = "ERROR: File not found. WARNING: Disk full.";
// 假设我们想按 "ERROR:" 或 "WARNING:" 来分割,并且想保留这些提示
$parts = preg_split('/(ERROR:|WARNING:)/', $logEntry, -1, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($parts);
/*
输出:
Array
(
    [0] => ERROR:
    [1] =>  File not found.
    [2] => WARNING:
    [3] =>  Disk full.
)
*/
?>
登录后复制

在这个例子里,

(ERROR:|WARNING:)
登录后复制

就是一个捕获组。当

preg_split()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

遇到

ERROR:
登录后复制

WARNING:
登录后复制

时,它会把它们当作分隔符,但因为我们使用了

PREG_SPLIT_DELIM_CAPTURE
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

标志,这些被捕获的分隔符也会被放进结果数组里。同时,我还加了

PREG_SPLIT_NO_EMPTY
登录后复制
登录后复制

,避免因为字符串开头没有内容而产生一个空的数组元素。

需要注意的是,只有正则表达式中的捕获组才会被这个标志捕获。如果你只是写了

/ERROR:|WARNING:/
登录后复制

而没有括号,那么即使加了

PREG_SPLIT_DELIM_CAPTURE
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

,分隔符也不会被捕获。这是个小细节,但有时候会让人困惑。理解这个,你就能更灵活地处理那些既要分割又要保留上下文信息的场景了。这在解析特定格式的日志、配置文件或者一些自定义协议时特别有用。

处理复杂或多模式分隔符时,

preg_split()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

有哪些进阶技巧?

当分隔符模式变得复杂起来,

preg_split()
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

的真正威力就展现出来了。我们不再满足于简单的逗号或空格,可能需要处理多种标点、不规则的空白,甚至特定格式的标记。

1. 使用字符类和量词处理多变的分隔符:
比如,你想把一个句子按任何标点符号(逗号、句号、问号、感叹号)和空白字符来分割,并且不关心它们出现的次数:

<?php
$sentence = "Hello, world! How are you?";
// 匹配一个或多个标点符号或空白字符
$words = preg_split('/[.,!?;:/s]+/', $sentence, -1, PREG_SPLIT_NO_EMPTY);
print_r($words);
/*
输出:
Array
(
    [0] => Hello
    [1] => world
    [2] => How
    [3] => are
    [4] => you
)
*/
?>
登录后复制

这里的

[.,!?;:/s]+
登录后复制

就是一个字符类,它会匹配方括号内的任何一个字符,

+
登录后复制

表示匹配一个或多个。

/s
登录后复制

是匹配任何空白字符的简写。这种写法非常简洁高效。

2. 使用管道符

|
登录后复制
登录后复制

进行“或”逻辑匹配:
如果你有几种完全不同的分隔符模式,它们之间没有直接的字符类关系,就可以用

|
登录后复制
登录后复制

(或)来连接。

<?php
$dataString =
登录后复制

以上就是如何用PHP将字符串按特定模式转为数组?正则表达式技巧的详细内容,更多请关注php中文网其它相关文章!

https://www.php.cn/faq/1478833.html

发表回复

Your email address will not be published. Required fields are marked *