Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/19.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 将括号内的文本转换为数组_Php_Regex - Fatal编程技术网

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

Php 将括号内的文本转换为数组,php,regex,Php,Regex,如果我有一个如下所示的字符串: $myString = "[sometext][moretext][993][112]This is a long text"; /(?:(?<digit>\[\d+])|(?<text>\[\w+])|(?<free>.+))/ 我想把它变成: $string = "This is a long text"; $arrayDigits[0] = 993; $arrayDigits[1] = 112; $arrayText[

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

$myString = "[sometext][moretext][993][112]This is a long text";
/(?:(?<digit>\[\d+])|(?<text>\[\w+])|(?<free>.+))/
我想把它变成:

$string = "This is a long text";
$arrayDigits[0] = 993;
$arrayDigits[1] = 112;
$arrayText[0] = "sometext";
$arrayText[1] = "moretext";
如何使用PHP实现这一点

我知道正则表达式是解决方案。请注意,
$myString
只是一个例子。可以有几个括号,而不是像我的示例中那样,每个括号都有两个

谢谢你的帮助

试试这个:

$s = '[sometext][moretext][993][112]This is a long text';
preg_match_all('/\[(\w+)\]/', $s, $m);
$m[1]
将包含制动器中的所有文本,之后您可以检查每个值的类型。另外,您可以使用两个
preg\u match\u all
:第一次使用pattern
/\[(\d+)\]/
(将返回数字数组),第二次使用pattern
/\[([a-zA-z]+)\]/
(将返回单词):


这就是我想到的

<?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);

您可以尝试以下方法:

<?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",
        ),
    );
*/

对于像您这样的情况,您可以使用命名子模式来“标记”字符串。只需一些小代码,就可以使用令牌数组轻松配置:

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

$groups = array(
    'digit' => '\[\d+]',
    'text' => '\[\w+]',
    'free' => '.+'
);
每个组都包含子模式及其名称。它们按顺序匹配,因此如果组数字匹配,则不会给文本一个机会(这在这里是必要的,因为
\d+
\w+
的子集)。然后可以将此阵列转换为完整阵列:

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

$pattern = sprintf('/(?:%s)/', implode('|', $groups));
现在可以在阵列中很好地访问匹配项:

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);
}
$subject=“[sometext][moretext][993][112]这是一个长文本”;
$groups=数组(
“数字”=>“\[\d+]”,
'文本'=>'\[\w+]',
“自由”=>“。+”
);
foreach($name=>&$subpattern形式的组)
$subpattern=sprintf(“(?%s)”,$name,$subpattern);
未设置($子模式);
$pattern=sprintf('/(?:%s)/',内爆('|',$groups));
if(preg_match_all($pattern,$subject,$matches))
{
$matches=array\u intersect\u key($matches,$groups);
$matches=array\u map('array\u filter',$matches);
$matches=array\u map('array\u value',$matches);
打印(匹配项);
}

regexp与爆炸、循环和一点if测试相比,不太可能成为解决方案。。。。为什么不首先使用合理的赋值呢?与其将这种疯狂的格式强制写入代码?@MarkBaker它基本上就像堆栈溢出一样,您可以在其中搜索“[php]搜索词”,这将只匹配带有php标记的问题。您能保证$myString始终包含相同的基本内容,并且顺序相同吗?i、 e.首先是数组文本,然后是数组数字,最后是一个未闭合的字符串
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);
}