如何用PHP将字符串按正则表达式转为数组?preg_split详解

preg_split函数通过正则表达式实现复杂字符串分割,支持模式化分隔符、限制分割数量、过滤空结果、捕获分隔符及获取子串偏移量,适用于灵活高效的字符串处理场景。

如何用php将字符串按正则表达式转为数组?preg_split详解

当需要在PHP中根据复杂的模式,而非简单的固定字符串来分割一个字符串时,

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

函数是你的首选工具。它利用正则表达式的强大能力,将输入字符串拆解成一个数组,这比传统的

explode
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

函数灵活得多。

解决方案:

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

函数的核心在于其能够识别并使用正则表达式作为分隔符。它的基本语法是

preg_split(string $pattern, string $subject, int $limit = -1, int $flags = 0): array
登录后复制

这里面几个参数都挺关键的:

  • $pattern
    登录后复制

    : 这就是你的正则表达式。它定义了你希望在哪些地方将字符串“切开”。记住,正则表达式需要用分隔符(比如

    /
    登录后复制

    )包裹起来。

  • $subject
    登录后复制

    : 你要处理的那个原始字符串。

  • $limit
    登录后复制

    : 一个可选参数,默认是

    -1
    登录后复制
    登录后复制

    。如果你指定了一个正整数,那么返回的数组最多只会有

    limit
    登录后复制

    个元素,最后一个元素会包含

    subject
    登录后复制

    字符串的剩余部分。如果设置为

    0
    登录后复制

    ,效果和

    -1
    登录后复制
    登录后复制

    一样。

  • $flags
    登录后复制

    : 这也是个可选参数,用来控制

    preg_split
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    的行为。有几个常用的旗标,比如

    PREG_SPLIT_NO_EMPTY
    登录后复制
    登录后复制
    登录后复制

    (不返回空字符串结果)、

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

    (捕获分隔符)、

    PREG_SPLIT_OFFSET_CAPTURE
    登录后复制
    登录后复制
    登录后复制
    登录后复制

    (同时返回匹配项的偏移量)。

举个例子,假设我们有一个字符串 “apple,banana;orange-grape”,我们想用逗号、分号或连字符来分割它。如果用

explode
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

,那就得写好几行代码循环处理,但

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

一行就能搞定:

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

<?php
$string = "apple,banana;orange-grape";
$parts = preg_split('/[,;-]/', $string);
print_r($parts);
/*
输出:
Array
(
    [0] => apple
    [1] => banana
    [2] => orange
    [3] => grape
)
*/

// 如果我们只想得到前两个元素,剩余的作为第三个元素
$limited_parts = preg_split('/[,;-]/', $string, 3);
print_r($limited_parts);
/*
输出:
Array
(
    [0] => apple
    [1] => banana
    [2] => orange-grape
)
*/
?>
登录后复制

在我看来,

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

的真正威力在于它能处理那些非固定的、模式化的分隔符。比如,你可能需要根据一个或多个空白字符来分割,或者根据HTML标签来拆分文本,这些都是

explode
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

无法胜任的。

PHP中的

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

explode
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

函数:何时选用?

这是一个很常见的问题,很多初学者都会在

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

explode
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

之间犹豫。简单来说,它们的核心区别在于分隔符的类型。

explode
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

函数只能使用一个简单的字符串作为分隔符,而

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

则可以使用复杂的正则表达式。

想象一下,你有一串用逗号分隔的商品名称,

explode(',', $string)
登录后复制

就能完美解决。但如果你的分隔符不总是逗号,有时候是逗号,有时候是分号,甚至是一串不确定的空白字符(比如一个或多个空格、制表符),这时候

explode
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

就显得力不从心了。你可能需要多次调用

explode
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

,或者先用

str_replace
登录后复制

统一分隔符,这无疑增加了代码的复杂度和维护成本。

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

的优势就在于此。通过编写一个适当的正则表达式,你可以一次性匹配所有可能的分隔符。例如,

/[,;/s]+/
登录后复制

就能匹配一个或多个逗号、分号或空白字符。所以,我的建议是:如果你的分隔符是固定的、单一的字符串,用

explode
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

更高效、更简洁;但如果分隔符是变化的、复杂的模式,或者你需要更高级的分割逻辑,那么毫无疑问,

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

是更强大的选择。过度使用

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

来处理简单的分隔符,虽然功能上没问题,但可能会带来轻微的性能损耗,而且代码可读性也不一定比

explode
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

好。

如何在

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

中有效处理空匹配项?

在使用

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

时,一个常见的“陷阱”就是生成意料之外的空字符串元素。这通常发生在分隔符出现在字符串的开头、结尾,或者两个分隔符紧密相连时。比如,字符串 “apple,,banana” 用逗号分割,你会得到

['apple', '', 'banana']
登录后复制

。很多时候,我们并不希望这些空字符串出现在最终结果中。

为了解决这个问题,

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

提供了一个非常实用的旗标:

PREG_SPLIT_NO_EMPTY
登录后复制
登录后复制
登录后复制

。顾名思义,这个旗标的作用就是告诉

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

不要将空的匹配项添加到结果数组中。

看个例子你就明白了:

<?php
$string_with_empty = "  apple   banana  ";
// 默认行为,会包含空字符串
$parts_default = preg_split('//s+/', $string_with_empty);
print_r($parts_default);
/*
输出:
Array
(
    [0] =>
    [1] => apple
    [2] =>
    [3] => banana
    [4] =>
)
*/

// 使用 PREG_SPLIT_NO_EMPTY 旗标
$parts_no_empty = preg_split('//s+/', $string_with_empty, -1, PREG_SPLIT_NO_EMPTY);
print_r($parts_no_empty);
/*
输出:
Array
(
    [0] => apple
    [1] => banana
)
*/
?>
登录后复制

显而易见,

PREG_SPLIT_NO_EMPTY
登录后复制
登录后复制
登录后复制

极大地简化了后处理的逻辑。你不再需要手动

array_filter
登录后复制

来去除空值。在实际开发中,尤其是在处理用户输入或者解析日志文件时,这个旗标几乎是必不可少的,它能让你的代码更健壮,结果更符合预期。

PHP

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

如何捕获分隔符或获取子串的偏移量?

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

的强大之处不仅在于它能按模式分割字符串,还在于它提供了额外的旗标来获取更多关于分割过程的信息,比如分隔符本身,或者每个分割出的子串在原字符串中的起始位置。这对于需要更精细控制和分析字符串的应用场景来说,简直是雪中送炭。

捕获分隔符:

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

有时候,我们不仅想知道分割后的内容是什么,还想知道具体是用哪个分隔符分割的。

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

旗标就能实现这一点。当你将这个旗标与

preg_split
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制
登录后复制

一起使用时,如果你的正则表达式中包含捕获组(用圆括号

()
登录后复制

包裹的部分),那么这些被捕获的分隔符也会作为独立的元素包含在结果数组中。

<?php
$data_string = "Name:John;Age:30|City:New York";
// 尝试分割,并捕获分隔符
$parts_with_delims = preg_split('/(:|;|/|)/', $data_string, -1, PREG_SPLIT_DELIM_CAPTURE);
print_r($parts_with_delims);
/*
输出:
Array
(
    [0] => Name
    [1] => :
    [2] => John
    [3] => ;
    [4] => Age
    [5] => :
    [6] => 30
    [7] => |
    [8] => City
    [9] => :
    [10] => New York
)
*/
?>
登录后复制

可以看到,冒号、分号和竖线这些分隔符都被捕获并插入到了结果数组中。这在解析复杂的数据格式,需要同时处理数据和其上下文(即分隔符的类型)时非常有用。

获取子串偏移量:

PREG_SPLIT_OFFSET_CAPTURE
登录后复制
登录后复制
登录后复制
登录后复制

另一个非常强大的旗标是

PREG_SPLIT_OFFSET_CAPTURE
登录后复制
登录后复制
登录后复制
登录后复制

。它不仅仅返回分割后的子字符串,还会返回每个子字符串在原始输入字符串中的字节偏移量。这对于需要知道每个部分原始位置的场景(比如语法高亮、错误定位)来说,是不可或缺的。

当使用

PREG_SPLIT_OFFSET_CAPTURE
登录后复制
登录后复制
登录后复制
登录后复制

时,结果数组中的每个元素本身又是一个数组,其中包含两个值:第一个是匹配到的子字符串,第二个是它在原始字符串中的起始偏移量。

<?php
$sentence = "Hello world, this is a test.";
// 分割并获取偏移量
$words_with_offsets = preg_split('//s+/', $sentence, -1, PREG_SPLIT_OFFSET_CAPTURE | PREG_SPLIT_NO_EMPTY);
print_r($words_with_offsets);
/*
输出:
Array
(
    [0] => Array
        (
            [0] => Hello
            [1] => 0
        )

    [1] => Array
        (
            [0] => world,
            [1] => 6
        )

    [2] => Array
        (
            [0] => this
            [1] => 12
        )

    [3] => Array
        (
            [0] => is
            [1] => 17
登录后复制

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

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

发表回复

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