将括号内的文本转换为PHP数组

时间:2012-02-26 09:48:48

标签: php regex

如果我有一个如下所示的字符串:

$myString = "[sometext][moretext][993][112]This is a long text";

我希望它变成:

$string = "This is a long text";
$arrayDigits[0] = 993;
$arrayDigits[1] = 112;
$arrayText[0] = "sometext";
$arrayText[1] = "moretext";

如何使用PHP执行此操作?

我理解正则表达式是解决方案。请注意$myString只是一个例子。可以有多个括号,而不是每个括号中的两个,如我的例子所示。

感谢您的帮助!

4 个答案:

答案 0 :(得分:1)

试试这个:

$s = '[sometext][moretext][993][112]This is a long text';
preg_match_all('/\[(\w+)\]/', $s, $m);

$m[1]将包含大括号中的所有文本,之后您可以检查每个值的类型。另外,您可以使用两个preg_match_all来检查:第一次使用模式/\[(\d+)\]/(将返回数字数组),在第二个模式/\[([a-zA-z]+)\]/中(将返回单词):< / p>

$s = '[sometext][moretext][993][112]This is a long text';
preg_match_all('/\[(\d+)\]/', $s, $matches);
$arrayOfDigits = $matches[1];
preg_match_all('/\[([a-zA-Z]+)\]/', $s, $matches);
$arrayOfWords = $matches[1];

答案 1 :(得分:1)

这就是我想出来的。

<?php

#For better display
header("Content-Type: text/plain");

#The String
$myString = "[sometext][moretext][993][112]This is a long text";

#Initialize the array
$matches = array();

#Fill it with matches. It would populate $matches[1].
preg_match_all("|\[(.+?)\]|", $myString, $matches);

#Remove anything inside of square brackets, and assign to $string.
$string = preg_replace("|\[.+\]|", "", $myString);

#Display the results.
print_r($matches[1]);
print_r($string);

之后,您可以迭代$matches数组并检查每个值以将其分配给新数组。

答案 2 :(得分:1)

对于像您这样的情况,您可以使用命名的子模式,以便“标记”您的字符串。使用一些代码,可以使用一系列令牌轻松配置:

$subject = "[sometext][moretext][993][112]This is a long text";

$groups = array(
    'digit' => '\[\d+]',
    'text' => '\[\w+]',
    'free' => '.+'
);

每个组都包含子模式及其名称。它们按顺序匹配,因此如果数字组匹配,则不会给 text 一个机会(这是必要的,因为\d+是其中的一个子集\w+)。然后,此数组可以变为完整模式:

foreach($groups as $name => &$subpattern)
    $subpattern = sprintf('(?<%s>%s)', $name, $subpattern);
unset($subpattern);

$pattern = sprintf('/(?:%s)/', implode('|', $groups));

模式如下:

/(?:(?<digit>\[\d+])|(?<text>\[\w+])|(?<free>.+))/

剩下要做的就是针对你的字符串执行它,捕获匹配并过滤它们以获得一些标准化输出:

if (preg_match_all($pattern, $subject, $matches))
{
    $matches = array_intersect_key($matches, $groups);
    $matches = array_map('array_filter', $matches);
    $matches = array_map('array_values', $matches);
    print_r($matches);
}

现在可以在数组中轻松访问匹配项:

Array
(
    [digit] => Array
        (
            [0] => [993]
            [1] => [112]
        )

    [text] => Array
        (
            [0] => [sometext]
            [1] => [moretext]
        )

    [free] => Array
        (
            [0] => This is a long text
        )

)

一次完整的例子:

$subject = "[sometext][moretext][993][112]This is a long text";

$groups = array(
    'digit' => '\[\d+]',
    'text' => '\[\w+]',
    'free' => '.+'
);

foreach($groups as $name => &$subpattern)
    $subpattern = sprintf('(?<%s>%s)', $name, $subpattern);
unset($subpattern);

$pattern = sprintf('/(?:%s)/', implode('|', $groups));

if (preg_match_all($pattern, $subject, $matches))
{
    $matches = array_intersect_key($matches, $groups);
    $matches = array_map('array_filter', $matches);
    $matches = array_map('array_values', $matches);
    print_r($matches);
}

答案 3 :(得分:0)

您可以尝试以下方式:

<?php

function parseString($string) {
    // identify data in brackets
    static $pattern = '#(?:\[)([^\[\]]+)(?:\])#';
    // result container
    $t = array(
        'string' => null,
        'digits' => array(),
        'text' => array(),
    );

    $t['string'] = preg_replace_callback($pattern, function($m) use(&$t) {
        // shove matched string into digits/text groups
        $t[is_numeric($m[1]) ? 'digits' : 'text'][] = $m[1];
        // remove the brackets from the text
        return '';
    }, $string);

    return $t;
}

$string = "[sometext][moretext][993][112]This is a long text";
$result = parseString($string);
var_dump($result);

/*
    $result === array(
        "string" => "This is a long text",
        "digits" => array(
            993,
            112,
        ),
        "text" => array(
            "sometext",
            "moretext",
        ),
    );
*/

(PHP5.3 - 使用闭包)